1072 Commits

Author SHA1 Message Date
1258fcdb7c fix strip exception logging 2023-07-11 10:52:34 +10:00
c662567384 Update 'booking.stripe.inc' 2023-07-11 10:50:52 +10:00
dce1865955 Update 'booking.stripe.inc' 2023-07-11 10:49:59 +10:00
4460f7e91c Update 'booking.stripe.inc' 2023-07-11 10:48:44 +10:00
ff9021ace0 Update 'booking.stripe.inc' 2023-07-11 10:46:52 +10:00
78445e3d45 Update 'booking.stripe.inc' 2023-07-11 10:44:43 +10:00
7b7fe113a8 Update 'booking.stripe.inc' 2023-07-11 10:43:35 +10:00
c979522c5f Update 'booking.stripe.inc' 2023-07-11 10:39:17 +10:00
32dfbdd76b improve error logging 2023-07-11 10:35:12 +10:00
52cda1cb78 try again 2023-07-11 10:33:21 +10:00
5c4f9029eb improve error handling 2023-07-11 10:32:06 +10:00
36f31fa0fc process error properly 2023-07-11 10:28:54 +10:00
494b6dfe2b try handling CardException 2023-07-11 10:26:55 +10:00
b470e309b3 Update another __toJSON() 2023-07-11 10:17:23 +10:00
7a5f6e2d3c Compatibility with newer API
replace __ toJSON() with toJSON()
2023-07-11 10:13:05 +10:00
2631bd7858 update link to stripe library 2023-07-11 09:48:07 +10:00
Nathan Coad
cb29873efa enhanced logging for invalid tempid token 2020-02-24 22:46:17 +11:00
Nathan Coad
f79f298978 improve query for person based on tempid 2020-02-24 22:41:23 +11:00
Nathan Coad
b11ce79cd7 add refund type to manual payment page 2020-02-13 18:12:23 +11:00
Nathan Coad
bac7acafc5 less debug 2019-09-17 22:28:30 +10:00
Nathan Coad
e2eb730d19 add distinct 2019-09-17 16:34:26 +10:00
Nathan Coad
907d4a0a82 improve formatting 2019-09-17 16:33:12 +10:00
Nathan Coad
4d5fa31fc8 no more debug 2019-09-17 16:30:12 +10:00
Nathan Coad
e8673e423e better format debug 2019-09-17 16:26:51 +10:00
Nathan Coad
29238335ab more debugs 2019-09-17 16:25:24 +10:00
Nathan Coad
82a39e44e3 test 2019-09-17 16:22:20 +10:00
Nathan Coad
02fc8b393d more debug 2019-09-17 16:18:57 +10:00
Nathan Coad
11fa3f4549 debug 2019-09-17 16:18:28 +10:00
Nathan Coad
884397a726 more sanity checking 2019-09-17 13:52:59 +10:00
Nathan Coad
e29e2d9f60 set default value 2019-09-17 13:51:34 +10:00
Nathan Coad
20a2984f49 size to maxlength 2019-09-17 13:49:52 +10:00
Nathan Coad
37a1d6867d fix concat 2019-09-17 13:46:52 +10:00
Nathan Coad
ac8e1d1657 test ecclesia autocomplete 2019-09-17 13:43:49 +10:00
Nathan Coad
58d786bd32 fix field validation 2019-09-15 09:29:03 +10:00
Nathan Coad
bc5a59604e enhance again 2019-09-15 09:26:16 +10:00
Nathan Coad
78f98b3a5d enhance medicare number description 2019-09-15 09:24:46 +10:00
Nathan Coad
4ce3df3339 make previous sw question configurable 2019-09-15 09:18:53 +10:00
Nathan Coad
7eb77b042f add email description 2019-09-15 07:20:53 +10:00
Nathan Coad
a0397fba7e tweaks 2019-09-14 18:59:45 +10:00
Nathan Coad
e353371af9 commit properly this time 2019-09-10 19:33:20 +10:00
Nathan Coad
0cb58768c3 disable variety timeslots of non-active event 2019-09-10 19:32:30 +10:00
Nathan Coad
a3472d6fb4 code cleanup 2019-09-10 19:08:26 +10:00
Nathan Coad
e8df551c94 fine tune query 2019-09-10 19:04:35 +10:00
Nathan Coad
10c098a7b6 tweak to query 2019-09-10 19:03:16 +10:00
Nathan Coad
683a47ec5e fix query 2019-09-10 19:02:21 +10:00
Nathan Coad
9e72fca856 do variety admin query properly 2019-09-10 19:01:17 +10:00
Nathan Coad
92dba91b02 fix variety admin to only show current event 2019-09-10 18:54:17 +10:00
Nathan Coad
01a02a7fb8 revert 2019-09-10 18:49:31 +10:00
Nathan Coad
752a44cb09 tweak 2019-09-10 18:48:38 +10:00
Nathan Coad
248a9691cd tweak to input type for variety form 2019-09-10 18:45:03 +10:00
Nathan Coad
37a138ba46 update notify email with prev sw count 2019-09-10 10:06:35 +10:00
Nathan Coad
86c4b7fcb3 update booking form for prev sw count 2019-09-10 10:00:09 +10:00
Nathan Coad
47fcbd04f2 update form to ask previous sw question 2019-09-10 09:49:26 +10:00
Nathan Coad
5d848794b9 add db field for previous sw coun 2019-09-10 09:34:49 +10:00
Nathan Coad
cf2d40033a fix missing character 2019-09-08 16:20:53 +10:00
Nathan Coad
aa1f0aa403 more descriptive text 2019-09-08 16:20:39 +10:00
Nathan Coad
1aa709fe54 fix require freestyle text 2019-09-08 16:19:48 +10:00
Nathan Coad
7869a9be5b make songchoice and freestyle text configurable 2019-09-08 16:17:39 +10:00
Nathan Coad
22bad5d8ef don't include empty social media link in email 2019-09-03 08:24:06 +10:00
Nathan Coad
5276e4bca1 add new colour to email template 2019-09-02 23:33:41 +10:00
Nathan Coad
fcfa97ff91 cleanup debugs 2019-09-02 21:59:35 +10:00
Nathan Coad
aebd90ee33 always load events include 2019-09-02 21:55:16 +10:00
Nathan Coad
572cf2797c and again 2019-09-02 21:51:57 +10:00
Nathan Coad
7938449565 update sql view on event change 2019-09-02 21:51:07 +10:00
Nathan Coad
06d5f608b9 more debug 2019-09-02 21:46:55 +10:00
Nathan Coad
c293b5423b debug booking_confirm_page 2019-09-02 21:41:36 +10:00
Nathan Coad
2f2dd62443 debug booking_view 2019-09-02 21:37:37 +10:00
Nathan Coad
be4854d933 fix email admin form for plain text emails 2018-09-18 10:24:12 +10:00
Nathan Coad
d6cb41ad64 remove unnecessary quote 2018-07-16 20:11:06 +10:00
Nathan Coad
a2542c02e4 try everything as a string 2018-07-16 17:36:22 +10:00
Nathan Coad
5c00b5a345 try string format for datetime 2018-07-16 17:32:35 +10:00
Nathan Coad
cea5e644c4 specify date format 2018-07-16 17:29:02 +10:00
Nathan Coad
6f23e54dff fix another variable name 2018-07-16 17:25:32 +10:00
Nathan Coad
dbee106fbc fix variable name 2018-07-16 17:23:49 +10:00
Nathan Coad
939f336489 test main csv output as excel 2018-07-16 17:22:42 +10:00
Nathan Coad
9c8ff253e4 tidy ups 2018-07-16 17:06:25 +10:00
Nathan Coad
5020b3466e only load travel include when necessary 2018-07-16 16:20:21 +10:00
71d92a4081 change font 2018-07-13 15:18:03 +10:00
0ede0d0677 set default font 2018-07-13 15:11:05 +10:00
27629729ca test change 2018-07-13 15:07:12 +10:00
f83e3a4b09 add debug 2018-07-13 15:03:43 +10:00
8327c33a3a heading style tweaks 2018-07-13 15:00:05 +10:00
683df04783 add style to header 2018-07-13 14:49:01 +10:00
42a91a9d7f no need to add quote marks for excel output 2018-07-13 14:37:21 +10:00
2f83967ba7 whoops 2018-07-13 14:34:43 +10:00
05d8e97edd change column headings format 2018-07-13 14:33:57 +10:00
930c0ec7ff add debug 2018-07-13 14:31:46 +10:00
1ee6d8e7c0 format excel headings properly 2018-07-13 14:27:32 +10:00
12cc3d33c9 tweak enclosure setting 2018-07-13 14:18:17 +10:00
90f0488448 insert variety registration if no record found already 2018-07-13 14:14:16 +10:00
b9b2f88299 tidy up spreadsheet info 2018-07-13 14:01:17 +10:00
2480c13641 bugfix 2018-07-13 13:57:26 +10:00
3bead3ad21 test with real data 2018-07-13 13:51:54 +10:00
feae543cf4 adjust code for other library 2018-07-13 13:46:18 +10:00
c5e1decb04 swap excel library 2018-07-13 13:45:03 +10:00
536546b7f9 test changes 2018-07-13 13:40:08 +10:00
a6781e0475 change loading of excel class 2018-07-13 13:17:24 +10:00
c1d6b05167 test of excel export 2018-07-13 13:09:31 +10:00
b8e2f852af fix mime type for csv 2018-07-12 08:08:44 +10:00
62ae5d89a4 escape column headings in CSV output 2018-07-12 08:03:37 +10:00
90de779c0c try fixing empty columns in CSV output 2018-07-12 07:59:59 +10:00
Nathan Coad
202d882bd6 tweak to text 2018-07-04 18:04:20 +10:00
Nathan Coad
62be5346fb put tableselect back 2018-07-03 23:23:56 +10:00
Nathan Coad
ccedba7b46 don't use tableselect to list variety sessions 2018-07-03 23:21:40 +10:00
Nathan Coad
ede732c310 handle empty variety sessions 2018-07-03 23:19:32 +10:00
Nathan Coad
cc8c326753 fix missing tid 2018-07-03 23:14:50 +10:00
Nathan Coad
ed6679c37b remove some unneeded logging 2018-07-01 17:20:13 +10:00
Nathan Coad
c77e077c29 code cleanup 2018-07-01 09:51:04 +10:00
Nathan Coad
ae9b61828c update user feedback 2018-06-30 14:52:14 +10:00
Nathan Coad
6754b1f997 update instructions 2018-06-30 14:50:54 +10:00
Nathan Coad
bc0cee9a9e fix data import not using nid 2018-06-30 14:46:57 +10:00
Nathan Coad
00fdb80b15 support data import via booking_tempid as well as nid 2018-06-30 14:40:09 +10:00
Nathan Coad
ae5b86a8a9 additional checking 2018-06-30 07:52:22 +10:00
Nathan Coad
c17e2025a3 fix room deletion validation 2018-06-30 07:44:49 +10:00
Nathan Coad
a30cb2c88c add debug 2018-06-30 07:38:53 +10:00
Nathan Coad
647a44e0ab exclude reading group from leader/helper summary 2018-06-28 14:51:42 +10:00
Nathan Coad
b71e61dcca change readinggroup colour order because Scott 2018-06-27 18:48:59 +10:00
Nathan Coad
3069c1a4c2 tweak 2018-06-26 19:11:07 +10:00
Nathan Coad
ca551094fd update studygroup calculation so only spouses booked in will get assigned to a group 2018-06-26 18:46:18 +10:00
Nathan Coad
d88a73f713 remove debug line 2018-06-26 18:23:47 +10:00
Nathan Coad
4431fc6e0c add preselection choice 2018-06-26 18:22:54 +10:00
Nathan Coad
c0322bb593 test reading group pre-selection 2018-06-26 18:19:19 +10:00
Nathan Coad
388ff80268 tweaks 2018-06-26 18:06:32 +10:00
Nathan Coad
598b6f653f add second attachment field 2018-06-26 18:04:38 +10:00
Nathan Coad
01b0b05428 modify ready for multiple email attachments 2018-06-26 17:58:40 +10:00
Nathan Coad
7e4f90cc54 test plupload in email form 2018-06-26 11:17:23 +10:00
Nathan Coad
fde5a01781 minor tweaks to token 2018-06-26 10:28:17 +10:00
Nathan Coad
33f5dcf34f change style 2018-06-26 10:16:16 +10:00
Nathan Coad
a634b85608 try different css 2018-06-26 10:12:46 +10:00
Nathan Coad
ce0b3792ba test attributes 2018-06-26 10:10:46 +10:00
Nathan Coad
ee95126760 leave out drupal_render 2018-06-26 09:43:54 +10:00
Nathan Coad
3379d34ee5 more testing 2018-06-26 09:42:12 +10:00
Nathan Coad
a01f955915 more testing 2018-06-26 09:34:30 +10:00
Nathan Coad
b083776c08 initial work for reading group token 2018-06-26 09:15:59 +10:00
Nathan Coad
16b0f6ee76 fix qr code heading 2018-06-22 17:44:22 +10:00
Nathan Coad
d3dbe66fcc make sure qr code can be edited and entered manually 2018-06-22 17:43:16 +10:00
Nathan Coad
516a119952 test default value 2018-06-22 17:37:29 +10:00
Nathan Coad
3811a181b3 test 2018-06-22 17:36:51 +10:00
Nathan Coad
26a43d620d test default value 2018-06-22 17:27:07 +10:00
Nathan Coad
1ab47f50b4 tweaks to import csv page 2018-06-22 17:22:31 +10:00
Nathan Coad
192032bab6 fix missing semicolon 2018-06-22 17:15:47 +10:00
Nathan Coad
94cf7b89b5 add QR code and change import csv page 2018-06-22 17:15:29 +10:00
Nathan Coad
8d83e08419 add some explanatory text 2018-06-21 12:02:20 +10:00
Nathan Coad
58d486dea9 remove debugging 2018-06-18 06:18:08 +10:00
Nathan Coad
9cf693585d tidy up readme 2018-06-17 10:30:02 +10:00
Nathan Coad
638e0807ac change default for meta token 2018-06-17 10:16:35 +10:00
Nathan Coad
33899cc483 add HTML filtering for meta tokens 2018-06-17 10:11:57 +10:00
Nathan Coad
37c3a3cc02 add extra meta token 2018-06-17 10:01:07 +10:00
Nathan Coad
28191d64d3 tweak formatting 2018-06-17 09:45:23 +10:00
Nathan Coad
eca4508853 add link to email definitions from manual email page 2018-06-17 09:44:14 +10:00
Nathan Coad
4bad8b2d46 cleanup 2018-06-17 09:18:29 +10:00
Nathan Coad
138f608a26 test 2018-06-17 09:17:37 +10:00
Nathan Coad
fb59029be1 add some error handling for studygroup csv report 2018-06-17 09:15:10 +10:00
Nathan Coad
f672e32ba0 multiple not supported 2018-06-17 05:08:04 +10:00
Nathan Coad
af942dadd4 test multiple attachments for emails 2018-06-17 05:02:29 +10:00
Nathan Coad
dee1438cf6 add some variable defaults 2018-06-17 04:45:11 +10:00
Nathan Coad
181645ecfb improve attachment detection 2018-06-17 04:42:30 +10:00
Nathan Coad
ea9ed2abf3 add debug 2018-06-17 04:41:18 +10:00
Nathan Coad
0e7d9a215a minor tweaks 2018-06-17 04:37:44 +10:00
Nathan Coad
ce2a9242e5 fix length 2018-06-16 21:55:41 +10:00
Nathan Coad
5fe2d8d88d test meta tokens 2018-06-16 21:53:17 +10:00
Nathan Coad
6f971767f0 fix attachment validators 2018-06-16 20:22:49 +10:00
Nathan Coad
08e9d220d6 tweak 2018-06-16 20:16:46 +10:00
Nathan Coad
84fcd20507 add attachment to email if it exists 2018-06-16 20:10:28 +10:00
Nathan Coad
04fc135818 fix 2018-06-16 19:59:41 +10:00
Nathan Coad
39449c2cad work on adding support for email attachments 2018-06-16 19:59:11 +10:00
Nathan Coad
b0ea07b789 test mime mail config 2018-06-16 19:11:31 +10:00
Nathan Coad
53d8919064 enhance formatting of studygroup-summary token 2018-06-16 18:57:39 +10:00
Nathan Coad
48dbb98c32 update the correct report 2018-06-16 18:48:42 +10:00
Nathan Coad
2e828060d0 store changes from studygroup definition form 2018-06-16 18:46:11 +10:00
Nathan Coad
ed45d52007 add more detail to study group definitions and email token 2018-06-16 18:39:55 +10:00
Nathan Coad
be5d1e8c2f test 2018-06-16 18:18:24 +10:00
Nathan Coad
e86ec94bb3 tweak 2018-06-16 17:51:26 +10:00
Nathan Coad
0e35a832c1 test email attachments 2018-06-16 17:47:49 +10:00
Nathan Coad
855c114b2b add "left" to number of spots remaining for variety sessions 2018-06-09 21:28:50 +10:00
Nathan Coad
8156084537 cleanup debugging 2018-05-22 13:26:16 +10:00
Nathan Coad
e9de00f774 even bigger 2018-05-22 13:24:26 +10:00
Nathan Coad
cf726772d6 change size of textbox 2018-05-22 13:23:50 +10:00
Nathan Coad
d1629c05ee change page definition for email ajax form 2018-05-22 13:21:34 +10:00
Nathan Coad
8a83a55160 cleanup 2018-05-22 13:13:57 +10:00
Nathan Coad
c774c17c2d test 2018-05-22 13:11:16 +10:00
Nathan Coad
5720f3150f test 2018-05-22 13:09:49 +10:00
Nathan Coad
03e6b91b2d debug 2018-05-22 13:08:14 +10:00
Nathan Coad
ceeef4837c test 2018-05-22 13:06:56 +10:00
Nathan Coad
75033a6735 fix again 2018-05-22 13:03:08 +10:00
Nathan Coad
e436f54974 fix 2018-05-22 13:02:34 +10:00
Nathan Coad
697d7d6b6a change button and wrapper 2018-05-22 13:02:21 +10:00
Nathan Coad
412167ff46 put button in fieldset 2018-05-22 12:59:26 +10:00
Nathan Coad
de6874c169 test workaround 2018-05-22 12:58:39 +10:00
Nathan Coad
319c65ccda test 2018-05-22 12:52:11 +10:00
Nathan Coad
23f837b7ac test 2018-05-22 12:50:40 +10:00
Nathan Coad
b0d25348ca change submit button disabled logic 2018-05-22 12:49:07 +10:00
Nathan Coad
b6680c22b3 debug 2018-05-22 12:37:20 +10:00
Nathan Coad
5054a241b0 test disabling save button 2018-05-22 12:34:46 +10:00
Nathan Coad
93881117e8 form tweaks 2018-05-22 12:32:09 +10:00
Nathan Coad
476140d6bc form tweak 2018-05-22 12:29:00 +10:00
Nathan Coad
9e87ed88df comment out deprecated email admin pages 2018-05-22 12:26:24 +10:00
Nathan Coad
bec6253981 remove debug 2018-05-22 12:24:04 +10:00
Nathan Coad
9f1a07e2fc fix 2018-05-22 12:21:23 +10:00
Nathan Coad
1501d6bd63 use form state input instead 2018-05-22 12:18:37 +10:00
Nathan Coad
10dc8b6f38 add form rebuild to submit hook 2018-05-22 12:13:55 +10:00
Nathan Coad
8fcec6e7f2 change form 2018-05-22 12:08:16 +10:00
Nathan Coad
5f98a72b69 debugging 2018-05-22 12:05:55 +10:00
Nathan Coad
3948a8bcd9 ajax form try setting default values 2018-05-22 12:04:48 +10:00
Nathan Coad
dfa6aa2314 add submit for email ajax form 2018-05-22 11:58:59 +10:00
Nathan Coad
ad87aaac72 testing value 2018-05-22 10:41:45 +10:00
Nathan Coad
cdc3347e45 test 2018-05-22 10:41:02 +10:00
Nathan Coad
d68a57f64a test 2018-05-22 10:40:15 +10:00
Nathan Coad
ddc5618101 test again 2018-05-22 10:39:33 +10:00
Nathan Coad
0ceecdc0f1 force plain text textarea for testng 2018-05-22 10:38:06 +10:00
Nathan Coad
c5179b059e test 2018-05-22 10:36:38 +10:00
Nathan Coad
9e20d49304 add debugging 2018-05-22 10:27:01 +10:00
Nathan Coad
c4a90e8776 change #default_value to #value 2018-05-22 10:24:15 +10:00
Nathan Coad
8309c5d37b fix 2018-05-22 10:23:15 +10:00
Nathan Coad
65463ecb76 work on better custom email definition form 2018-05-22 10:19:29 +10:00
Nathan Coad
d75667d32e add permission for variety session form 2018-05-18 11:12:56 +10:00
Nathan Coad
c4d2173794 add configurable text at the start of the variety session registration form 2018-05-18 10:58:18 +10:00
Nathan Coad
0607a562c2 reduce debug 2018-05-15 20:52:38 +10:00
Nathan Coad
928c9a320f debug reduction 2018-05-15 20:50:50 +10:00
Nathan Coad
5121216f66 style 2018-05-15 14:34:49 +10:00
Nathan Coad
cddaadb2ff dont hide fieldset 2018-05-15 14:31:42 +10:00
Nathan Coad
b6b17de5b8 tidy up 2018-05-15 14:25:33 +10:00
Nathan Coad
4874ad650f test 2018-05-15 14:24:07 +10:00
Nathan Coad
5246897238 test 2018-05-15 13:44:51 +10:00
Nathan Coad
bc4820c0a8 fix typo 2018-05-15 13:43:21 +10:00
Nathan Coad
fa213595f8 test hiding elements 2018-05-15 13:42:51 +10:00
Nathan Coad
5ca13ca6a5 turn off ajax for nid field 2018-05-15 13:34:37 +10:00
Nathan Coad
d80ee5dc3d input tel number 2018-05-15 13:21:25 +10:00
Nathan Coad
85194238bd change booking_nid input to tel type 2018-05-15 13:16:57 +10:00
Nathan Coad
3ca14dbd34 check for empty values 2018-05-15 13:06:37 +10:00
Nathan Coad
38e32a1e58 update callback 2018-05-15 13:05:24 +10:00
Nathan Coad
edcf3d36bf Update feedback based on query result 2018-05-15 13:03:35 +10:00
Nathan Coad
4ffef1a6c4 change prefix/suffix for form 2018-05-15 13:00:01 +10:00
Nathan Coad
272094e27e test redrawing whole form 2018-05-15 12:55:42 +10:00
Nathan Coad
292725233f add surname to variety session form 2018-05-15 12:51:00 +10:00
Nathan Coad
80f911f9af fixed logging message 2018-05-10 10:08:51 +10:00
Nathan Coad
684f66c5d4 add booking_variety_ids to excluded_keys for hook_update 2018-05-08 21:37:45 +10:00
Nathan Coad
a9065a28b7 take out some debugging from travel form 2018-05-08 19:26:48 +10:00
Nathan Coad
e5dd203d1d tweak travel form permissions 2018-05-08 19:24:42 +10:00
Nathan Coad
a951c033ee fix links to variety session admin pages 2018-05-05 21:47:44 +10:00
Nathan Coad
69fd7f9541 change page title for viewing variety sessions 2018-05-05 21:46:42 +10:00
Nathan Coad
c4c47dd8a8 change path for variety session admin pages 2018-05-05 21:45:38 +10:00
Nathan Coad
f3eeedaea1 fix incorrect variable 2018-05-05 21:37:25 +10:00
Nathan Coad
780221c475 fix typo 2018-05-05 21:36:41 +10:00
Nathan Coad
bf07ed21a3 debug 2018-05-05 21:35:24 +10:00
Nathan Coad
7dea27104b fix hidden field in form 2018-05-05 21:30:29 +10:00
Nathan Coad
19d6b1d432 fix out of date variable name 2018-05-05 21:27:20 +10:00
Nathan Coad
3601e7492b update delete functionality 2018-05-05 21:26:18 +10:00
Nathan Coad
7c25b701e3 two way comparison between old and new variety sessions 2018-05-05 21:21:22 +10:00
Nathan Coad
8ef3b83adf invert logic 2018-05-05 21:13:52 +10:00
Nathan Coad
7d9db5af8f clean up logic 2018-05-05 21:05:35 +10:00
Nathan Coad
8198b48462 try again 2018-05-05 20:58:58 +10:00
Nathan Coad
1d78d73a9d tweak logic again 2018-05-05 20:54:19 +10:00
Nathan Coad
8e9b0f9709 fix logic 2018-05-05 20:51:02 +10:00
Nathan Coad
5fd8d5ce0e debug 2018-05-05 20:48:37 +10:00
Nathan Coad
caad0538fe debug 2018-05-05 20:43:32 +10:00
Nathan Coad
3ad86cfead handle missing timeslot 2018-05-05 20:42:19 +10:00
Nathan Coad
82c9f23b78 fix logic 2018-05-05 20:38:17 +10:00
Nathan Coad
78473752e4 debugging 2018-05-05 20:36:17 +10:00
Nathan Coad
5cb02b49b7 fix redirect 2018-05-05 20:31:42 +10:00
Nathan Coad
4a902166f7 fix typo 2018-05-05 20:30:53 +10:00
Nathan Coad
35eac186b8 work on update queries 2018-05-05 20:29:03 +10:00
Nathan Coad
01048189a9 fix query 2018-05-05 20:24:55 +10:00
Nathan Coad
1cedef106c more work on edit variety submit hook 2018-05-05 20:23:28 +10:00
Nathan Coad
aa288a4d4f mroe typos 2018-05-05 15:31:51 +10:00
Nathan Coad
7770fbfe2b fix query 2018-05-05 15:30:51 +10:00
Nathan Coad
967176b7b4 typo 2018-05-05 15:29:28 +10:00
Nathan Coad
49a2a68072 fix logic errors 2018-05-05 15:28:00 +10:00
Nathan Coad
81a2a27895 work on form to edit registration for variety sessions 2018-05-05 15:20:55 +10:00
Nathan Coad
d56d6bbc92 check session still exists 2018-05-05 14:57:36 +10:00
Nathan Coad
4fe8c86245 debug 2018-05-05 14:55:28 +10:00
Nathan Coad
ecf0342310 use separate query for session data 2018-05-05 14:51:37 +10:00
Nathan Coad
261f0201be change left join to join 2018-05-05 14:46:40 +10:00
Nathan Coad
a56400b6e4 fix query 2018-05-05 14:45:25 +10:00
Nathan Coad
bc365a005c join the variety sessions table to timeslots table 2018-05-05 14:44:48 +10:00
Nathan Coad
43d69907e0 fix callback 2018-05-05 13:36:53 +10:00
Nathan Coad
3c6687892f initial work on variety session report 2018-05-05 13:32:29 +10:00
Nathan Coad
83c2c498db fix redirect path 2018-05-05 12:23:15 +10:00
Nathan Coad
5e2f47133f fix typo 2018-05-05 12:21:29 +10:00
Nathan Coad
e6f46f554d complete submit hook for variety session form 2018-05-05 12:20:58 +10:00
Nathan Coad
be12693e1c fix callback 2018-05-05 12:09:28 +10:00
Nathan Coad
10f0087a0b fix edit session link 2018-05-05 12:08:31 +10:00
Nathan Coad
654968dc57 test variety session edit form 2018-05-05 12:05:35 +10:00
Nathan Coad
be7b7db7d8 remove rowcount 2018-05-04 23:05:01 +10:00
Nathan Coad
48a6db74ed test rowcount 2018-05-04 23:04:37 +10:00
Nathan Coad
624d49d66c and again 2018-05-04 23:02:04 +10:00
Nathan Coad
16f3a82c81 change query again 2018-05-04 23:01:15 +10:00
Nathan Coad
7cd93a09f1 fix variable name 2018-05-04 23:00:01 +10:00
Nathan Coad
63a17dcefc change query again 2018-05-04 22:58:44 +10:00
Nathan Coad
9ac93d701c test result 2018-05-04 22:56:50 +10:00
Nathan Coad
b82360598f test 2018-05-04 22:55:19 +10:00
Nathan Coad
b32b719a29 fix query 2018-05-04 22:52:08 +10:00
Nathan Coad
04bfd9d876 use different query 2018-05-04 22:49:49 +10:00
Nathan Coad
b283cadcf9 fix query 2018-05-04 22:45:44 +10:00
Nathan Coad
01ffc3424e debug 2018-05-04 22:44:09 +10:00
Nathan Coad
e17b190d2f dont use object of type stdClass as array 2018-05-04 22:43:14 +10:00
Nathan Coad
46001d1700 fix typo 2018-05-04 22:42:27 +10:00
Nathan Coad
6a056c80eb fix permissions 2018-05-04 22:41:36 +10:00
Nathan Coad
9a4b327250 add CSV report for variety session 2018-05-04 22:38:48 +10:00
Nathan Coad
b376faca6f store variety session details as json 2018-05-04 22:12:45 +10:00
Nathan Coad
d18b56e19e add redirect to front page 2018-05-03 10:35:31 +10:00
Nathan Coad
1d913c156e fix 2018-05-03 10:31:07 +10:00
Nathan Coad
a90960619d use rowCount 2018-05-03 10:30:01 +10:00
Nathan Coad
2ca29c0d46 hopefully fix query 2018-05-03 10:25:02 +10:00
Nathan Coad
6c908d29f2 fix validation 2018-05-03 10:18:02 +10:00
Nathan Coad
59d04fea5d actual cleanup 2018-05-03 10:13:15 +10:00
Nathan Coad
7f8c3386b6 cleanup 2018-05-03 10:13:05 +10:00
Nathan Coad
ade7c5d584 check for previous registration 2018-05-03 09:44:15 +10:00
Nathan Coad
4d0d5b2979 variety registration submit function 2018-05-03 09:38:33 +10:00
Nathan Coad
2521a6fd96 update mysql view for variety session registration ids 2018-05-03 08:53:10 +10:00
Nathan Coad
59cbcb9c52 change form_set_error to drupal_set_message 2018-05-03 08:42:33 +10:00
Nathan Coad
fe632ee847 try to get form to rebuild if session is full 2018-05-03 08:34:38 +10:00
Nathan Coad
6ef447921b validation error if session is full 2018-05-03 08:32:16 +10:00
Nathan Coad
3cfca677ea improve validate 2018-05-03 08:29:58 +10:00
Nathan Coad
cd1493ef4a skip vaidation if ajax callback 2018-05-03 08:27:21 +10:00
Nathan Coad
558b72e663 debug 2018-05-03 08:21:51 +10:00
Nathan Coad
732b6c63be fix debug 2018-05-03 08:17:41 +10:00
Nathan Coad
8bcf1d51b1 debugging 2018-05-03 08:16:09 +10:00
Nathan Coad
8b133cf160 tidy up and variety validation work 2018-05-03 08:09:29 +10:00
Nathan Coad
145e914f5e perform validation 2018-05-02 16:57:46 +10:00
Nathan Coad
b0a7b7007a restored missing function 2018-05-02 16:50:34 +10:00
Nathan Coad
7f4f8455ee cleanup 2018-05-02 16:33:18 +10:00
Nathan Coad
76c82fae85 test 2018-05-02 15:56:50 +10:00
Nathan Coad
427f1dd2e7 test partial form rebuild 2018-05-02 15:52:47 +10:00
Nathan Coad
346414ba3b test partial form update 2018-05-02 15:51:14 +10:00
Nathan Coad
67d449ca4e test 2018-05-02 15:46:40 +10:00
Nathan Coad
295333c230 test replacing whole form 2018-05-02 15:44:13 +10:00
Nathan Coad
6c3ce18d2d test 2018-05-02 15:32:50 +10:00
Nathan Coad
7a3a43a837 test 2018-05-02 15:32:01 +10:00
Nathan Coad
c9705ce122 test 2018-05-02 15:30:40 +10:00
Nathan Coad
a507c3f219 test ajax_deliver 2018-05-02 15:29:18 +10:00
Nathan Coad
a12351c15e test 2018-05-02 15:22:17 +10:00
Nathan Coad
ba9b7d86ee test 2018-05-02 15:21:27 +10:00
Nathan Coad
d6f4b8e6be test just using $fieldname 2018-05-02 15:19:55 +10:00
Nathan Coad
a5efdeadf0 test 2018-05-02 15:18:19 +10:00
Nathan Coad
a5f49c7301 test 2018-05-02 14:59:26 +10:00
Nathan Coad
a61dd8cdc4 debug form_state 2018-05-02 14:54:45 +10:00
Nathan Coad
b5614a80e4 add submit function 2018-05-02 14:53:34 +10:00
Nathan Coad
187f056197 try unsetting input data 2018-05-02 14:50:33 +10:00
Nathan Coad
c4cd0e63cb test 2018-05-02 14:44:32 +10:00
Nathan Coad
d7108419c1 test 2018-05-02 14:41:05 +10:00
Nathan Coad
9917b5990b test 2018-05-02 14:40:22 +10:00
Nathan Coad
27c4920165 test 2018-05-02 14:39:08 +10:00
Nathan Coad
11dd6a2edf test 2018-05-02 14:23:25 +10:00
Nathan Coad
f65c99a80e test 2018-05-02 14:21:21 +10:00
Nathan Coad
ef66bf4842 try not recreating form element 2018-05-02 14:20:10 +10:00
Nathan Coad
f1fa34d6bc test default value 2018-05-02 14:17:34 +10:00
Nathan Coad
88d5ee6cbf test default value 2018-05-02 14:15:01 +10:00
Nathan Coad
5cf0962d1f test 2018-05-02 14:13:57 +10:00
Nathan Coad
11122b9696 test 2018-05-02 14:06:01 +10:00
Nathan Coad
2be119ca1c change drupal_render to just render 2018-05-02 14:05:14 +10:00
Nathan Coad
44fcfef61f test 2018-05-02 14:02:40 +10:00
Nathan Coad
ccc5a8d772 debug 2018-05-02 13:59:02 +10:00
Nathan Coad
b804eec1df debug 2018-05-02 13:56:25 +10:00
Nathan Coad
22d6e0a03d debug 2018-05-02 13:51:59 +10:00
Nathan Coad
5beb81a47f testing 2018-05-02 13:48:52 +10:00
Nathan Coad
0874913fb8 debugging 2018-05-02 13:46:16 +10:00
Nathan Coad
3b0d8c5628 progress 2018-05-02 13:42:25 +10:00
Nathan Coad
f244562358 update 2018-05-02 13:30:42 +10:00
Nathan Coad
3c8ed7f1e3 specify whole form element 2018-05-02 13:27:17 +10:00
Nathan Coad
c440c769d2 test again 2018-05-02 13:25:43 +10:00
Nathan Coad
2ab0fbe0d8 making progress 2018-05-02 13:21:50 +10:00
Nathan Coad
7e84ad2b0d test null 2018-05-02 13:20:53 +10:00
Nathan Coad
4e2f7f74f8 test 2018-05-02 13:17:44 +10:00
Nathan Coad
f8a9f76e20 test 2018-05-02 13:15:39 +10:00
Nathan Coad
29e71e658d test again 2018-05-02 13:09:15 +10:00
Nathan Coad
82c6db47ed test 2018-05-02 13:04:39 +10:00
Nathan Coad
2075dbfc92 formatting 2018-05-02 11:58:57 +10:00
Nathan Coad
2c59c26cbd make session values dynamic 2018-05-02 11:49:47 +10:00
Nathan Coad
c1957a6c83 fix query 2018-05-02 11:29:50 +10:00
Nathan Coad
340cfa503d develop variety session form 2018-05-02 11:20:26 +10:00
Nathan Coad
7ceacf9f6d remove excessively verbose log message 2018-05-02 10:12:21 +10:00
Nathan Coad
0d6334e5b4 tweak default text 2018-04-22 10:02:09 +10:00
Nathan Coad
4364104454 revert logic 2018-04-19 09:47:47 +10:00
Nathan Coad
fc05fb9e4e fix logic 2018-04-19 09:44:50 +10:00
Nathan Coad
e7a0999da8 fix missing default text 2018-04-19 09:39:54 +10:00
Nathan Coad
50c464265d add separate email for waiting list promotion fully paid 2018-04-19 09:29:05 +10:00
Nathan Coad
43a174db79 fix array entry 2018-04-10 08:46:35 +10:00
Nathan Coad
d3dd2384f0 add email preselection for refund required 2018-04-10 08:40:07 +10:00
Nathan Coad
c5f9be5f7c revert db query optimise 2018-01-29 21:46:35 +11:00
Nathan Coad
09235cb589 optimise query 2018-01-29 21:28:17 +11:00
Nathan Coad
a8ec4e31b3 change debug message 2018-01-29 21:26:08 +11:00
Nathan Coad
54e74b412e fix query 2018-01-29 21:24:27 +11:00
Nathan Coad
9e5fdc450f update waitinglist page 2018-01-29 21:23:52 +11:00
Nathan Coad
288efddf8e rewrite waiting list query 2018-01-29 21:22:23 +11:00
Nathan Coad
404021335c add debugging 2018-01-29 17:48:52 +11:00
Nathan Coad
1ad5da11d3 add debug 2018-01-29 17:43:08 +11:00
Nathan Coad
2a5fce9dc4 fix update 2018-01-29 17:38:24 +11:00
Nathan Coad
e083fdaaca start implementing stored waiting list position 2018-01-29 16:59:46 +11:00
Nathan Coad
0c9754e41b add booking uuid as a token 2018-01-19 11:03:31 +11:00
Nathan Coad
796b910a85 remove some debugging 2018-01-18 20:06:09 +11:00
Nathan Coad
c45dfa21b9 cleanup 2018-01-18 17:48:05 +11:00
Nathan Coad
0e427a8416 fix regex quoting and escaping 2018-01-18 17:46:44 +11:00
Nathan Coad
dc7353e1e2 more debugging 2018-01-18 17:44:11 +11:00
Nathan Coad
5d3a7ffbf1 add debugging 2018-01-18 17:41:01 +11:00
Nathan Coad
c29d8a7a21 update to use preg_replace_callback 2018-01-18 17:37:35 +11:00
Nathan Coad
b25a858054 actually save this time 2018-01-18 17:26:46 +11:00
Nathan Coad
a1b392a675 put ucname function back for node updates 2018-01-18 17:26:24 +11:00
Nathan Coad
c70b05922d change _booking_ucname function to handle names like McClure 2018-01-18 12:13:56 +11:00
Nathan Coad
584376bf25 minor tweaks 2018-01-18 11:52:46 +11:00
Nathan Coad
fb7084012c change message slightly 2018-01-15 23:38:23 +11:00
Nathan Coad
c422dcedd8 clarified message about unnecessary balance emails 2018-01-15 23:37:27 +11:00
Nathan Coad
6e8adebeb5 remove unnecessary <pre> tag 2018-01-15 23:31:22 +11:00
Nathan Coad
87b53bbc24 bugfix for email preview 2018-01-15 23:27:36 +11:00
Nathan Coad
cfa5b01db8 change from t() to regular string in tokens 2018-01-15 23:16:19 +11:00
Nathan Coad
0f2e415baf change link tokens to href if html email enabled 2018-01-15 23:08:59 +11:00
Nathan Coad
46180afaeb tweaks to studygroup pages 2018-01-14 12:35:28 +11:00
Nathan Coad
3a25d690f4 more debug 2018-01-14 11:43:58 +11:00
Nathan Coad
db64bff16e change nid lookup in person query 2018-01-14 11:43:04 +11:00
Nathan Coad
132570540f fix 2018-01-14 11:39:29 +11:00
Nathan Coad
d79ff5289a bugfix 2018-01-14 11:38:28 +11:00
Nathan Coad
18233ba6ee change check for db query 2018-01-14 11:36:58 +11:00
Nathan Coad
51bf95dfeb reduce unnecessary db query 2018-01-14 11:31:09 +11:00
Nathan Coad
9ac1c170a0 more fixing 2018-01-14 11:28:45 +11:00
Nathan Coad
2b47366511 fix more logic 2018-01-14 11:16:01 +11:00
Nathan Coad
7849265288 attempt fix 2018-01-14 11:13:12 +11:00
Nathan Coad
fa383cb515 test travel 2018-01-14 11:02:53 +11:00
Nathan Coad
fdf1534542 debug travel form 2018-01-14 10:57:34 +11:00
Nathan Coad
7a5cc19de9 fix travel form 2018-01-14 10:54:56 +11:00
Nathan Coad
37317e0ea7 test 2018-01-13 14:17:34 +11:00
Nathan Coad
acdae37921 another test 2018-01-13 14:16:13 +11:00
Nathan Coad
e470b7a9b1 test updates for outlook on windows 2018-01-13 14:14:44 +11:00
Nathan Coad
5865803250 mail template fix 2018-01-13 13:55:36 +11:00
Nathan Coad
011a4fac70 cleanup 2018-01-13 13:36:35 +11:00
Nathan Coad
2f91fef245 cleanup of logic 2018-01-13 13:32:59 +11:00
Nathan Coad
6a7260eec8 change logic for early access code 2018-01-13 13:31:32 +11:00
Nathan Coad
4bc7c8745c allow previous year to be selected for event dates 2018-01-13 13:23:17 +11:00
Nathan Coad
c0f076b889 fix logic for discounted booking rate 2018-01-13 13:13:30 +11:00
Nathan Coad
0395b406a5 explain why form caching isnt effective 2017-11-25 20:35:31 +11:00
Nathan Coad
6ff5ae7790 actually create cache table in update hook 2017-11-25 17:51:55 +11:00
Nathan Coad
85249b475f fix missing bracket 2017-11-25 17:46:05 +11:00
Nathan Coad
0f260a1675 test caching booking form 2017-11-25 17:45:35 +11:00
9a720ce93e change layout of template admin page 2017-09-16 14:47:31 +10:00
8e6164a45c fix colours in template 2017-09-16 14:44:36 +10:00
a9796b3f47 another mail template fix 2017-09-16 14:41:44 +10:00
036d911272 formatting fix in mail template 2017-09-16 14:27:18 +10:00
a8ff994a9d code cleanup 2017-09-16 12:15:05 +10:00
332dcabd52 make email generation more consistent 2017-09-15 17:24:07 +10:00
d1f82c4ecb remove link color since it is not defined in mail template 2017-09-15 16:45:44 +10:00
981303635d fix incorrect link 2017-09-15 16:42:41 +10:00
141d78c64d update 2017-09-15 16:34:36 +10:00
aaa13c6988 set image in template 2017-09-15 16:32:36 +10:00
5afd8f6f05 bugfix 2017-09-15 16:21:36 +10:00
0bb9d0bbf7 debugging 2017-09-15 16:19:47 +10:00
e8531a8baf more work 2017-09-15 16:13:54 +10:00
8187deacdb store nav links from form 2017-09-15 15:49:42 +10:00
e0eb865706 update 2017-09-15 15:45:45 +10:00
266449d21c update for nav links 2017-09-15 15:45:14 +10:00
af138df744 test theme updates 2017-09-15 15:07:31 +10:00
8f1319c79a mailtemplate stored as json in variable table 2017-09-15 15:00:28 +10:00
19978d51f5 more work 2017-09-15 13:09:35 +10:00
009e9732b2 fix 2017-09-15 12:55:02 +10:00
76ac3fbead start adding html email template customisability 2017-09-15 12:54:33 +10:00
e1cb00858f more template updates 2017-09-12 17:34:06 +10:00
aa9adc3320 tweak html template 2017-09-12 15:16:52 +10:00
254c09ded7 remove unncessary html code from template 2017-09-12 15:15:15 +10:00
d01be3b8a1 make html email links dynamic 2017-09-12 15:07:42 +10:00
557b99966d process names fields to always be Title Case 2017-09-12 08:44:21 +10:00
9910b523c6 bugfix 2017-09-09 19:49:53 +10:00
f200fbc9b2 layout fix 2017-09-09 19:46:19 +10:00
308c8be4a4 bugfix 2017-09-09 19:45:40 +10:00
9ad6291d0c fix typo 2017-09-09 19:28:48 +10:00
6e57f78d26 add preselection for unpaid people 2017-09-09 19:27:05 +10:00
ca634916c0 more debug 2017-09-09 11:51:39 +10:00
414c2ef8ae remove unnecessary emoji handling 2017-09-09 11:28:06 +10:00
784bf46378 change emoji removal to optional 2017-09-09 11:26:46 +10:00
a7d24fb16c bugfix earlyaccess code not present 2017-09-09 10:44:49 +10:00
461c6b1053 bugfix earlyaccess code not defined 2017-09-09 10:42:50 +10:00
3155c277ef check every booking form input value for emojis 2017-09-09 10:39:08 +10:00
895b3b80e6 test better emoji removal 2017-09-09 10:32:46 +10:00
c3f0f191f3 comment update 2017-09-09 00:16:58 +10:00
b6460fa681 strip emoji when updating node title in presave hook 2017-09-09 00:14:57 +10:00
5fbdfd1cd4 try different function for stripping emoji 2017-09-09 00:06:56 +10:00
f3cd3f0745 remove emoji from node title also 2017-09-08 23:57:03 +10:00
4135790c64 handle booking_passport_issue_date properly 2017-09-08 23:45:37 +10:00
2b20549707 exclude booking_deposit_timestamp also 2017-09-08 23:40:52 +10:00
83800b155e correctly handle dob again 2017-09-08 23:39:02 +10:00
c27f2c1005 add some field exclusions to update hook 2017-09-08 23:37:00 +10:00
5e616019dd more debug 2017-09-08 23:28:14 +10:00
f741694491 add debug 2017-09-08 23:26:41 +10:00
088648812e handle node updates more generically 2017-09-08 23:24:51 +10:00
0763037aec add code to strip emoji from registration data when entered by user 2017-09-08 23:04:57 +10:00
258febf238 reduce debugging messages 2017-09-07 22:20:39 +10:00
78ebc3ac27 fixes 2017-09-07 16:09:14 +10:00
54ad2404be fix dreference 2017-09-07 16:05:33 +10:00
aff52e4349 bugfix 2017-09-07 16:03:18 +10:00
14fb815c97 update email summary fields 2017-09-07 15:48:24 +10:00
1f3040ebe5 bugfix variable out of scope 2017-09-07 14:34:10 +10:00
c522f94dfa remove debug messages for html email 2017-09-02 00:13:11 +10:00
5c2715f28a email template tweaks 2017-09-01 23:44:25 +10:00
31c02c153d fix image locations 2017-09-01 18:11:02 +10:00
e2d8a9d89b update email template for sw2018 2017-09-01 18:06:46 +10:00
e90b2ebb62 retire random facts 2017-08-29 23:26:36 +10:00
e3fee20b7d add freestyle text to node display 2017-08-29 22:49:42 +10:00
79b2b0e505 change song choice to freestyle text 2017-08-29 22:48:26 +10:00
d568cf2043 allow discounted rate for early access registrations 2017-08-29 22:36:08 +10:00
57bf81dfa4 add checks for earlyaccess 2017-08-29 22:27:43 +10:00
a707ab2fd0 add more info about discounted payment rates 2017-08-29 22:19:47 +10:00
d023e67da5 increase booking_medical_conditions 2017-08-29 08:09:51 +10:00
31b98fb623 update medical conditions field 2017-08-29 08:02:05 +10:00
23ff234bae more explanation 2017-08-26 19:30:03 +10:00
9f9c437037 remove br outside div 2017-08-26 19:27:06 +10:00
1fb55cc4d5 comment out debug statements 2017-08-26 19:25:22 +10:00
557c5a8a3d change instruction to inside wrapper 2017-08-26 19:21:49 +10:00
73d6dabecf bold text 2017-08-26 19:18:59 +10:00
686f3c5eef add linebreak 2017-08-26 19:16:58 +10:00
8ba365ed97 fix css 2017-08-26 19:16:30 +10:00
3f42c97ef2 change wrapper id 2017-08-26 19:13:44 +10:00
388e52462d more debug 2017-08-26 19:11:28 +10:00
d6e76f6e81 different debug 2017-08-26 19:09:31 +10:00
1037efed19 moar debug 2017-08-26 19:07:07 +10:00
6730787ea1 add debug 2017-08-26 19:06:27 +10:00
99fa4d4584 add postive feedback 2017-08-26 19:03:11 +10:00
3a150be2f3 test ajax validation of early access code 2017-08-26 19:01:42 +10:00
12fdc944ab add implementation of random_int for pre-PHP7 2017-08-22 21:46:17 +10:00
8e3b8e75c6 add link to earlyaccess code in config page 2017-08-22 21:40:58 +10:00
cf8736d43b change song choice to mandatory 2017-08-22 21:35:42 +10:00
8999130762 remove test 2017-08-22 21:32:40 +10:00
890cb7159d test 2017-08-22 21:27:44 +10:00
ee4a13bdd5 change node view 2017-08-22 21:26:58 +10:00
b2292c0eca fix node view 2017-08-22 21:21:46 +10:00
0b8b257364 fix missing space in query 2017-08-22 21:19:38 +10:00
512f863058 add update price to current event query 2017-08-22 21:18:55 +10:00
d9107c0d48 update query for prices 2017-08-22 21:10:44 +10:00
c48f31613d add song choice and early access code to regn node view 2017-08-22 21:04:45 +10:00
8bb01c00ee make song choice configurable option 2017-08-18 10:28:51 +10:00
e324071ad9 add song choice 2017-08-18 10:24:45 +10:00
9294e17e3f revert tests 2017-07-02 22:47:57 +10:00
43d9ab4e4c test 2017-07-02 22:47:20 +10:00
84a44b9845 another test 2017-07-02 22:45:49 +10:00
3d1a323a3b test hiding text format options 2017-07-02 22:41:02 +10:00
574fd3ecb7 fix function contents 2017-07-02 09:18:30 +10:00
7f3a8f94f8 fix function name 2017-07-02 09:17:00 +10:00
45d473a646 move logistics emails also 2017-07-02 09:16:05 +10:00
8444477ab2 move custom emails to their own page 2017-07-02 09:12:35 +10:00
899fd83499 email updates 2017-07-02 09:08:39 +10:00
dc2f10fee3 fix missing tokens 2017-07-01 23:32:32 +10:00
71c0cbb26b fix email imploding for html mail of summaries 2017-07-01 23:08:06 +10:00
409e00fc84 missed one 2017-07-01 23:02:27 +10:00
527b961f7c add footer and finish html theme coding 2017-07-01 23:01:42 +10:00
4ad18bf7fd move footer definition to theme call 2017-07-01 22:51:42 +10:00
627b1767e8 move mail footer to email admin page 2017-07-01 22:44:51 +10:00
0fd7f95baf add mail footer for HTML email 2017-07-01 22:41:51 +10:00
2c20f04a1d update fix 2017-07-01 16:51:32 +10:00
0b3a2f2273 hack removed 2017-06-29 16:58:11 +10:00
5701fee75f temp hack 2017-06-29 16:33:24 +10:00
eb78639b06 add earlyaccess code to mysql view 2017-06-29 16:30:45 +10:00
b85f17b362 fixes 2017-06-29 16:23:04 +10:00
7df9904aaf add node id to earlyaccess codes table 2017-06-29 16:19:49 +10:00
13f5125ccc another fix 2017-06-29 16:14:34 +10:00
49ee2846a2 bugfix 2017-06-29 16:13:21 +10:00
238c8a8ed7 revert changes 2017-06-29 16:10:36 +10:00
6459d7d243 change query 2017-06-29 15:48:54 +10:00
3fcbe0f9b6 fix join 2017-06-29 15:47:10 +10:00
7e908389dd add missed update 2017-06-29 15:45:43 +10:00
ac8ed27d63 rename table and fields to remove _regn for earlyaccess codes 2017-06-29 15:45:11 +10:00
acfbd806ef better now 2017-06-29 15:06:56 +10:00
1111b91b73 making progress 2017-06-29 15:04:24 +10:00
2b01006b0a try resetting 2017-06-29 15:03:32 +10:00
ff036eab50 more debugs 2017-06-29 15:00:30 +10:00
f786e02efa rewind pointer after use 2017-06-29 14:52:19 +10:00
c18752c56a try a different fix 2017-06-29 14:51:09 +10:00
1f31169ca6 fix header array 2017-06-29 14:49:20 +10:00
d75b946bdb debugging 2017-06-29 14:46:44 +10:00
4cf96a2a68 missing header 2017-06-29 14:43:35 +10:00
bb9942fd3b row added too early to output 2017-06-29 14:43:03 +10:00
22c07cc832 fix another typo 2017-06-29 14:41:34 +10:00
b14edc70a2 fix extra brace 2017-06-29 14:40:38 +10:00
b109cb792f fix 2017-06-29 14:36:45 +10:00
381d61b85d add CSV report for earlyaccess codes 2017-06-29 14:35:40 +10:00
241f1e02e2 implement earlyaccess code summary 2017-06-29 14:23:18 +10:00
5f9465dd59 make notification email more html friendly 2017-06-29 13:20:09 +10:00
16e34ebfd1 fix subject line 2017-06-29 13:14:37 +10:00
a0f5f259fd update theming for notification email 2017-06-29 13:12:11 +10:00
f4116040c1 sanitise data before inserting 2017-06-29 13:03:10 +10:00
cd83d885d8 test tweak to booking_insert 2017-06-29 12:55:47 +10:00
fab55d7aef fix 2017-06-29 12:47:58 +10:00
99a54e7f76 add debug statement 2017-06-29 12:46:24 +10:00
9d5ebccb0e fix menu path 2017-06-29 12:41:57 +10:00
b5d9b5ea7f add earlyaccess code generation 2017-06-29 12:40:47 +10:00
e90d02f46e start work on admin page for early access codes 2017-06-29 12:10:19 +10:00
0c975086e5 form tweak 2017-06-29 11:54:02 +10:00
3d68e2a8ce more validation 2017-06-29 11:51:19 +10:00
b0cc61de6c logic fix 2017-06-29 11:40:48 +10:00
d1dc168197 early access code development 2017-06-29 11:38:26 +10:00
f7345875f8 another tweak 2017-06-29 11:27:38 +10:00
7cfe389e62 template tweak 2017-06-29 11:26:04 +10:00
5a8ddd4a5e icon changes 2017-06-29 11:24:35 +10:00
d6f6b78f24 theme tweaks 2017-06-29 11:22:37 +10:00
977ba0769b tweaks 2017-06-27 22:32:31 +10:00
d613b5b736 fix email IDs 2017-06-27 22:08:40 +10:00
83d3b57d1d add emails types to hook 2017-06-27 22:06:19 +10:00
c2f8d71664 update email preview for html mails 2017-06-27 22:00:35 +10:00
2d37380939 send html emails for more mail types 2017-06-27 21:56:14 +10:00
2f1050cf7f missed one 2017-06-27 21:15:50 +10:00
a1dd635148 adjust the rest of the fields for emails 2017-06-27 21:14:35 +10:00
c94c90dd94 blah 2017-06-27 20:56:29 +10:00
39f174401a test more fields 2017-06-27 20:50:41 +10:00
298ca2d48a add warning 2017-06-27 20:48:14 +10:00
4c9cc6f519 fix 2017-06-27 20:46:43 +10:00
73185c28f3 increase flexibility in form 2017-06-27 20:44:35 +10:00
db45ff0ddb test 2017-06-27 20:33:08 +10:00
9c198c27d6 test 2017-06-27 20:32:02 +10:00
fd9289a57d tst 2017-06-27 20:30:47 +10:00
4768fe7ba1 test 2017-06-27 20:28:46 +10:00
d0f8d44516 handle mailsystem register/cleanup better 2017-06-27 19:04:52 +10:00
554a73623e stop trying to be so smart 2017-06-27 18:29:16 +10:00
2559d03a8a revert to linking images 2017-06-27 18:26:04 +10:00
5c0bbbc805 fix image type 2017-06-27 18:10:32 +10:00
a28775e5b8 fix 2017-06-27 18:07:36 +10:00
677afbd060 test inline image 2017-06-27 18:05:25 +10:00
cad04505f3 image test in template 2017-06-27 17:41:46 +10:00
a84626e96a fix 2017-06-27 17:30:17 +10:00
25f0a2af03 add registration email template test 2017-06-27 17:28:49 +10:00
8fcb858f2e fix typo 2017-06-27 13:29:39 +10:00
a7ef7e36cd remove dependency 2017-06-27 13:27:36 +10:00
0f2511205d more debug 2017-06-27 13:22:12 +10:00
51d89c19c6 more debug 2017-06-27 13:18:15 +10:00
c45c5739a9 debug 2017-06-27 13:15:05 +10:00
526060696e test 2017-06-27 13:01:09 +10:00
9cc9140a73 set mail_system variable 2017-06-27 12:59:11 +10:00
e8e73cfe75 test again 2017-06-27 12:49:52 +10:00
9fd05f98da test 2017-06-27 12:48:55 +10:00
e589f6b0a5 debugging 2017-06-27 12:43:09 +10:00
39dd2e43b8 add missing include 2017-06-27 12:34:21 +10:00
44931adb82 add dependency on mailsystem 2017-06-27 12:31:36 +10:00
0fe7189f10 test adding hook 2017-06-27 12:29:28 +10:00
d4ac574142 get html textarea value 2017-06-27 12:19:35 +10:00
7e99092df7 theming of email body 2017-06-27 12:17:54 +10:00
b1b900dfb3 adding theming 2017-06-27 12:08:23 +10:00
b2f1372950 add schema update code 2017-06-27 10:46:47 +10:00
3d588081ee handle array value 2017-06-27 10:15:13 +10:00
ce2914cf03 debug 2017-06-27 09:20:38 +10:00
c02e933cb8 bugfix 2017-06-27 08:47:11 +10:00
ec7a9ea0d8 test full_html for textareas 2017-06-27 08:29:21 +10:00
d88df40702 bugfix 2017-06-26 22:30:55 +10:00
b530dba1ad logic change for early access 2017-06-26 22:30:11 +10:00
f951c6bc9b add form elements 2017-06-26 22:18:34 +10:00
e332a35fa0 initial work on early access codes 2017-06-26 21:55:10 +10:00
3af311609c bugfix redeclaration of $node 2017-06-26 20:37:47 +10:00
Nathan Coad
6004c3250c cleanup 2017-04-15 13:37:26 +10:00
Nathan Coad
f02b4bf53b fix manual email to not include reference to travel form when not enabled 2017-01-11 08:06:29 +11:00
Nathan Coad
e89f48b17d fix missing variable definition 2016-08-22 10:38:20 +10:00
Nathan Coad
f79f812e4e fix confirmation form to handle stripe 2016-08-22 09:54:51 +10:00
d906c2e220 tidy up some disused code 2016-08-10 15:14:00 +10:00
Nathan Coad
af648cce84 change some debugging 2016-07-23 12:23:44 +10:00
Nathan Coad
a24a60fb77 temp testing to workaround stripe bug 2016-07-23 12:09:44 +10:00
Nathan Coad
3cbb0334c3 add country checking for stripe charges 2016-07-23 12:00:46 +10:00
Nathan Coad
9e26b69edf cleanup formatting in email functions 2016-07-23 11:36:19 +10:00
Nathan Coad
cc7d8680f3 change db type from varchar to text 2016-07-23 11:20:14 +10:00
Nathan Coad
ef938eb58f update db insert as well 2016-07-23 11:17:00 +10:00
Nathan Coad
b0fca9b101 db update to handle stripe response size 2016-07-23 11:16:27 +10:00
Nathan Coad
51bdc6da2f store the json response from stripe in the db 2016-07-23 11:13:03 +10:00
Nathan Coad
35731c3835 debug tweak 2016-07-23 11:07:33 +10:00
Nathan Coad
cd37a85ad6 fix incorrect token 2016-07-23 10:24:01 +10:00
Nathan Coad
cb97f64ecd tidy up some code locations 2016-07-23 10:16:12 +10:00
Nathan Coad
581b7d7537 customise payment button 2016-07-23 10:07:34 +10:00
Nathan Coad
f6ee9d11a7 customise checkout form 2016-07-23 10:03:53 +10:00
Nathan Coad
dd70dfd5a3 bugfix 2016-07-23 09:48:27 +10:00
Nathan Coad
f4456a86f0 add admin field for stripe checkout logo 2016-07-23 09:36:16 +10:00
Nathan Coad
9f50f2f2c3 remove attempts to detect amex card in js 2016-07-23 09:26:07 +10:00
Nathan Coad
28a520aea6 try something else 2016-07-23 09:21:47 +10:00
Nathan Coad
385ba3c83b js testing for amex 2016-07-23 09:18:44 +10:00
Nathan Coad
69bae12146 tidy up balance page 2016-07-22 16:09:23 +10:00
Nathan Coad
2cbfda6cf7 fix for international stripe fee token 2016-07-22 16:02:23 +10:00
Nathan Coad
07078de79b add some debugging to balance payment page 2016-07-22 15:54:40 +10:00
Nathan Coad
dd9e4ac822 temporary workaround for tokens 2016-07-22 15:49:02 +10:00
Nathan Coad
87247d87f4 more stripe specific tokens 2016-07-22 15:46:03 +10:00
Nathan Coad
04396cda56 add rounding to amount charged 2016-07-22 15:30:00 +10:00
Nathan Coad
1878fc72e1 add dynamic amount in js for stripe 2016-07-22 15:25:27 +10:00
Nathan Coad
297a0acf28 js bugfix after variable rename 2016-07-22 15:19:16 +10:00
Nathan Coad
a7d33c6239 bugfix incorrect variable name 2016-07-22 15:17:58 +10:00
Nathan Coad
b102d4c496 use foreign transaction rate for amex cards 2016-07-22 15:15:19 +10:00
Nathan Coad
5f8f17e798 store charge token in db 2016-07-22 14:42:58 +10:00
Nathan Coad
a40e6a9d8a more cleanup 2016-07-22 11:58:39 +10:00
Nathan Coad
3794fece83 tidy up requirements check 2016-07-22 11:51:12 +10:00
Nathan Coad
a103d34276 fix differently 2016-07-22 11:47:22 +10:00
Nathan Coad
72647c02d9 derefence fix 2016-07-22 11:46:18 +10:00
Nathan Coad
21abb9331a use proper value in status display 2016-07-22 11:44:44 +10:00
Nathan Coad
e9c996949d stripe library check debug 2016-07-22 11:42:23 +10:00
Nathan Coad
a97f610661 add stripe library status to status report 2016-07-22 11:37:28 +10:00
Nathan Coad
b132ed9682 add code to handle stripe fees 2016-07-22 11:21:27 +10:00
Nathan Coad
75e7f08111 js dev 2016-07-22 10:32:55 +10:00
Nathan Coad
578bea1aa6 js progress 2016-07-22 10:28:59 +10:00
Nathan Coad
5c00f6e342 js debugging 2016-07-22 10:26:37 +10:00
Nathan Coad
089304cf19 js revert 2016-07-22 10:21:13 +10:00
Nathan Coad
dc01c12ae2 js update 2016-07-22 10:00:19 +10:00
Nathan Coad
1beffbadf4 js mods 2016-07-22 09:59:05 +10:00
Nathan Coad
ac9b330eb7 further js mods 2016-07-22 09:53:56 +10:00
Nathan Coad
b6bcfacead work on storing stripe token 2016-07-22 09:31:49 +10:00
Nathan Coad
2614e25364 test js mods 2016-07-22 09:26:27 +10:00
Nathan Coad
ee93be90d8 fix references 2016-07-22 09:13:02 +10:00
Nathan Coad
6836f3bc00 fix function names 2016-07-22 09:06:52 +10:00
Nathan Coad
c0d2e11172 further implementation work for stripe integration 2016-07-22 09:01:39 +10:00
Nathan Coad
6172866bf4 progress stripe implementation 2016-07-21 15:43:51 +10:00
Nathan Coad
62060f075a add token for stripe 2016-07-21 15:23:01 +10:00
Nathan Coad
3e6ea4936b modify to use Checkout form 2016-07-21 15:17:11 +10:00
Nathan Coad
cab49b68f5 change library config 2016-07-21 12:07:38 +10:00
Nathan Coad
28df961b87 test library settings 2016-07-21 11:55:39 +10:00
Nathan Coad
9a3687e1d1 change stripe library config 2016-07-21 11:44:45 +10:00
Nathan Coad
cb0b3b5cad more debug 2016-07-21 11:26:50 +10:00
Nathan Coad
770a1e1da9 testing 2016-07-21 11:24:11 +10:00
Nathan Coad
f5dc4836ce change error handling 2016-07-21 11:00:15 +10:00
Nathan Coad
c654b83177 change namespace for stripe function calls 2016-07-21 10:55:07 +10:00
Nathan Coad
28599d8d1f fix function call 2016-07-21 10:40:06 +10:00
Nathan Coad
b594364e0d fixes 2016-07-21 10:35:04 +10:00
Nathan Coad
2ffa185fb9 stripe initial test 2016-07-21 10:29:57 +10:00
Nathan Coad
d095db14af proper fix 2016-07-21 09:19:59 +10:00
Nathan Coad
9fdc391b8d fix 2016-07-21 09:18:26 +10:00
Nathan Coad
aef96242a8 fix 2016-07-21 09:15:55 +10:00
Nathan Coad
2d5e7eb23c add stripe library hook 2016-07-21 09:13:59 +10:00
Nathan Coad
9567f9c105 add stripe explanation 2016-07-21 08:41:13 +10:00
Nathan Coad
fd9b5e0045 fix missing comma 2016-07-21 08:27:19 +10:00
Nathan Coad
48abf172a8 add stripe config options to admin page 2016-07-21 08:23:28 +10:00
Nathan Coad
f76d8be329 Merge branch 'master' of gitlab.coadcorp.com:drupal/booking 2016-07-21 08:13:58 +10:00
Nathan Coad
ec6b7399e4 commence adding stripe integration 2016-07-21 08:12:14 +10:00
e68ea21185 Update README.md 2016-07-21 08:07:26 +10:00
350e2fe180 Update README.md 2016-07-21 08:05:00 +10:00
Nathan Coad
bc881f3abb Merge branch 'master' of gitlab.coadcorp.com:drupal/booking 2016-07-21 07:41:34 +10:00
e404501cda Add option for including age groups 2016-07-03 23:47:03 +10:00
f2c6858634 Make age output optional 2016-07-03 23:45:09 +10:00
a6dc9a61d2 change colours 2016-06-29 19:17:59 +10:00
5c8b7d662f undo test 2016-06-29 19:16:05 +10:00
7002020efd test 2016-06-29 19:13:01 +10:00
352ef58033 test 2016-06-29 19:10:57 +10:00
4512dd9107 css test 2016-06-29 19:09:13 +10:00
4e4dcf1cc9 testing change from ID to class for role highlighting 2016-06-29 19:05:09 +10:00
9011220ecc add css for reserve helper 2016-06-29 17:52:08 +10:00
9ceabb97c7 fix missing references to reserve helper 2016-06-29 16:45:32 +10:00
af95616e87 add missing column heading 2016-06-29 16:43:32 +10:00
7934d0718c add reserve helper role to studygroups 2016-06-29 16:40:05 +10:00
a4da6d2d93 code refactor 2016-06-28 21:48:55 +10:00
a1c091a03c tweak to text in _booking_leader_helper_email_summary token 2016-06-28 21:41:59 +10:00
ecaa11d70d bugfix 2016-06-28 17:21:56 +10:00
d6619aa5ee update 2016-06-28 13:36:22 +10:00
3694e37db4 cleanup 2016-06-28 13:33:33 +10:00
06df0a1856 add ensuite info to booking_rooms_view_form() as well as change to an associative array 2016-06-28 13:30:16 +10:00
69442d30b5 add ensuite info to room allocations page 2016-06-28 13:17:38 +10:00
d5d45512c6 update room number field to be an integer 2016-06-28 13:12:55 +10:00
1aa9f6cfbe move room label to dedicated column 2016-06-27 11:53:25 +10:00
d2dc154518 add room description to room allocation page 2016-06-27 11:51:26 +10:00
b3b4fef4d2 add room descriptions to view room allocations page 2016-06-27 11:48:33 +10:00
63226d93f0 fix USN 2016-06-27 11:34:50 +10:00
805c639e5d add room description field 2016-06-27 11:34:24 +10:00
622c84314b tweak debug messages for editing a person's studygroups 2016-06-27 10:56:31 +10:00
70168189fb tweak to travel report 2016-06-27 10:44:10 +10:00
4550028fd6 re-arrange travel report columns 2016-06-27 10:41:43 +10:00
91efbb80d6 also add highlighting for people that want accommodation 2016-06-26 22:14:51 +10:00
f628e41677 attach csv properly 2016-06-26 22:07:28 +10:00
49b97729f1 css update 2016-06-26 22:04:53 +10:00
ad31433dad fix 2016-06-26 22:03:00 +10:00
f09811990d add css for people flying to study week 2016-06-26 22:02:15 +10:00
c8c6f50a04 fix 2016-06-26 21:55:30 +10:00
ed160830ff add state to travel summary report 2016-06-26 21:54:07 +10:00
67dd4d6336 add link to travel form 2016-06-26 21:48:58 +10:00
3a0daab0eb few more tweaks 2016-06-26 21:46:47 +10:00
c59f3bda09 tweaks to travel report 2016-06-26 21:45:19 +10:00
d88159c25a remove people no longer coming from travel report 2016-06-26 21:41:05 +10:00
582110a752 rename report 2016-06-26 21:37:58 +10:00
d44e0d9592 fix 2016-06-26 21:35:48 +10:00
7e248a8bf3 add travel summary report 2016-06-26 21:34:28 +10:00
Nathan Coad
e30f2f7d6f more formatting tweaks 2016-06-24 15:40:41 +10:00
Nathan Coad
f97dd6545d formatting tweak 2016-06-24 15:38:28 +10:00
Nathan Coad
4df8c4f059 add age to studygroup CSV report 2016-06-24 15:21:17 +10:00
Nathan Coad
087f0405ef fix message quoting 2016-06-24 14:35:57 +10:00
Nathan Coad
3bdaa51657 fix the separation logic 2016-06-24 14:34:04 +10:00
Nathan Coad
49e93895e8 change debug message again 2016-06-24 14:28:54 +10:00
Nathan Coad
bfc6de4ba5 fix debug message 2016-06-24 14:27:31 +10:00
Nathan Coad
66f634f600 test 2016-06-24 14:23:50 +10:00
Nathan Coad
2de599cae2 bugfix 2016-06-24 14:18:16 +10:00
Nathan Coad
1ac064be32 add keep separate flag 2016-06-24 14:16:35 +10:00
Nathan Coad
54984e89e5 fix array references 2016-06-24 12:44:46 +10:00
Nathan Coad
d5a810badc enhance debugging 2016-06-24 12:41:49 +10:00
Nathan Coad
d864f9b3bd pass some other missing variables to function 2016-06-24 12:37:09 +10:00
Nathan Coad
afdbd91222 move allocation to separate function 2016-06-24 12:34:49 +10:00
Nathan Coad
39d6a31e3b fix parameter ordering 2016-06-24 12:16:19 +10:00
Nathan Coad
1322956634 work on tidying up study group calculation functions 2016-06-24 12:07:37 +10:00
a38efd654c change sort order of studygroup CSV report 2016-06-23 22:30:27 +10:00
eee81539b6 update room allocation autocomplete to include node id 2016-06-23 22:22:49 +10:00
e52d6ffc65 add manually assigned column to booking_studygroups_view_form() 2016-06-23 22:05:22 +10:00
b175f1cc24 rearrange fields booking node theming 2016-06-23 22:00:13 +10:00
83ed03f7ff logic change in studygroup calculations for committee members 2016-06-23 18:36:42 +10:00
e69ebc95bd remove deprecated studygroup calculation function 2016-06-23 18:28:39 +10:00
4adc2b4ee5 fix 2016-06-23 16:33:34 +10:00
b310d3a02b fix 2016-06-23 16:31:09 +10:00
76e2357c78 update 2016-06-23 16:30:10 +10:00
d4d1f9e14e Merge branch 'master' of gitlab.coadcorp.com:drupal/booking 2016-06-23 16:28:26 +10:00
193f6d9400 continue work on manual allocation flag 2016-06-23 16:28:20 +10:00
Nathan Coad
f7c5a15108 commence work on manual allocation flag 2016-06-23 16:25:55 +10:00
Nathan Coad
ccac5cd293 fix reading group handling 2016-06-23 14:17:08 +10:00
Nathan Coad
eb71552a84 remove debug statement 2016-06-23 13:55:25 +10:00
Nathan Coad
94e7a7049f handle stiuation when leader/helper wasn't previously allocated to the study group in any session 2016-06-23 13:53:14 +10:00
Nathan Coad
7288dd7b78 use colours for leader/helper edit form if readings group is true 2016-06-23 13:35:49 +10:00
Nathan Coad
0eba6ef073 use autocomplete leader/helper edit form in table for studygroups 2016-06-23 11:46:01 +10:00
Nathan Coad
6a7fae9bd8 fix person change bug 2016-06-23 11:40:58 +10:00
Nathan Coad
4ae6c21ad4 fix case where changing leader from one group to another removed them completely 2016-06-23 11:30:25 +10:00
Nathan Coad
7c8f325954 message update 2016-06-23 11:26:12 +10:00
Nathan Coad
065c87b4e2 handle person addition to leader/helper edit form 2016-06-23 11:24:36 +10:00
Nathan Coad
1214279bda change autocomplete to include node ids 2016-06-23 11:19:29 +10:00
Nathan Coad
019247c16a fix 2016-06-23 11:15:03 +10:00
Nathan Coad
4a8e95def3 remove debug statement 2016-06-23 11:13:05 +10:00
Nathan Coad
1ab68096b7 fix 2016-06-23 11:12:10 +10:00
Nathan Coad
c9d0aca9d3 add update code for leader/helper edit form 2016-06-23 11:10:31 +10:00
Nathan Coad
c7b35cd3fc add code for removal of leader/helper role 2016-06-23 10:57:08 +10:00
Nathan Coad
7ff32988b0 debugging 2016-06-23 10:21:25 +10:00
Nathan Coad
f398980225 wip 2016-06-23 10:11:08 +10:00
Nathan Coad
af3660d974 test 2016-06-23 09:56:33 +10:00
Nathan Coad
bfb3ac9d48 update 2016-06-23 09:04:37 +10:00
Nathan Coad
04fd9e3e76 initial development for autocomplete leader/helper selection 2016-06-23 08:53:27 +10:00
f270892027 fix medicare field again 2016-06-23 06:36:55 +10:00
06f1abbc60 add committee tag to study group output 2016-06-22 23:08:47 +10:00
7847afcf5d add human-readable studygroup names for CSV headings if option is enabled in admin page 2016-06-22 23:03:21 +10:00
f26af4a0fb change CSV heading description 2016-06-22 22:45:07 +10:00
925907cadb change medicare required logic 2016-06-22 22:33:58 +10:00
bbd96ea440 change reading group csv output to use team colours for heading 2016-06-22 18:14:07 +10:00
e2f640ab30 change fudge factor again 2016-06-22 18:08:32 +10:00
d0e5d370eb change group fudge factor 2016-06-22 18:01:36 +10:00
2493f7eb98 update readings group colours if someone is indivually reassigned 2016-06-22 17:54:14 +10:00
567c141f2a tidyup 2016-06-22 17:35:34 +10:00
f73d52ef40 update reading goup colour processing to use booking_is_readinggroup flag 2016-06-22 17:30:21 +10:00
1d4af9ac39 tweak to phone number handling in CSV 2016-06-18 19:16:35 +10:00
5a4ee8054f add same functionality to hook_update() 2016-06-18 16:20:19 +10:00
9a0aadfbc6 booking form post submit trigger update bf/gf for matching attendee 2016-06-18 16:15:48 +10:00
0aa7d4381e remove test email preselection 2016-06-18 14:07:39 +10:00
ee350ed26b reorganise functions into appropriate files 2016-06-18 14:04:38 +10:00
Nathan Coad
1e912f526c add logistics email token 2016-06-18 12:06:01 +10:00
9fe4bfe101 edit node fix 2016-06-14 22:58:21 +10:00
894a798d96 tweak lucky number function 2016-06-14 22:52:00 +10:00
7d9c9ee566 change debug 2016-06-13 13:45:22 +10:00
d39e6ba4bc code cleanup 2016-06-11 15:33:44 +10:00
7cc1ba9be9 format debug message better 2016-06-11 15:29:02 +10:00
a7f95395bf fixes 2016-06-11 15:23:53 +10:00
33c040453a validation improvements 2016-06-11 15:23:16 +10:00
9c263eae95 refactor booking form 2016-06-11 15:14:57 +10:00
f6e227ba56 more internal form tweaks 2016-06-11 14:29:11 +10:00
88da4bd0d0 fix 2016-06-11 14:27:21 +10:00
87f3dc109e change debug 2016-06-11 14:25:26 +10:00
7366ce52cf debug 2016-06-11 14:23:44 +10:00
5e6a06f97a add guardian email address 2016-06-11 14:19:27 +10:00
b816de11d2 remove old passport and flight info from cahaya 2016-06-11 13:59:13 +10:00
Nathan Coad
67112c71b4 add preselection for leaders/helpers 2016-06-08 15:36:20 +10:00
Nathan Coad
f23c896a12 bugfix 2016-06-08 14:45:05 +10:00
Nathan Coad
d809089a7f code cleanup 2016-06-08 14:44:01 +10:00
Nathan Coad
d70b577638 bugfix 2016-06-08 14:36:07 +10:00
Nathan Coad
c46966033f restrict summary to people booked in or waiting list 2016-06-08 14:34:11 +10:00
Nathan Coad
04e43f4ccd change width 2016-06-08 14:28:05 +10:00
Nathan Coad
c96ae20cf8 fix reference 2016-06-08 14:26:19 +10:00
Nathan Coad
d54b7e6c12 fix sql 2016-06-08 14:21:01 +10:00
Nathan Coad
283fe7d9dd test 2016-06-08 14:17:03 +10:00
Nathan Coad
bffc40d2d7 test 2016-06-08 14:14:50 +10:00
Nathan Coad
d1d9560d02 debugging 2016-06-08 14:12:31 +10:00
Nathan Coad
527fb363e7 bugfix 2016-06-08 12:27:44 +10:00
Nathan Coad
fd64685504 change logic 2016-06-08 12:26:54 +10:00
Nathan Coad
a689917c39 fix query 2016-06-08 12:13:20 +10:00
Nathan Coad
12f75f8445 bugfix 2016-06-08 12:06:40 +10:00
Nathan Coad
e3030316d6 new report for leaders/helpers 2016-06-08 12:03:41 +10:00
Nathan Coad
4d06713fea remove debug message 2016-06-08 09:58:14 +10:00
Nathan Coad
ddc3a8c358 debug 2016-06-08 09:56:36 +10:00
Nathan Coad
5e13321a3c add married text 2016-06-08 09:51:20 +10:00
Nathan Coad
c589d81e14 more progress 2016-06-08 09:46:42 +10:00
Nathan Coad
8e014e2350 more work on email preview 2016-06-08 09:37:07 +10:00
Nathan Coad
0dc753ab3e add email preview 2016-06-08 09:00:02 +10:00
6414502cfe fix again 2016-06-04 13:35:41 +10:00
680799e3e4 fix fix formatting 2016-06-04 13:35:00 +10:00
d87a3eba86 formatting 2016-06-04 13:32:11 +10:00
804396ddf7 fix formatting 2016-06-04 13:29:31 +10:00
372c4d4f80 logic fix 2016-06-04 12:57:47 +10:00
8cce7121a3 hide special requirements fieldset if not needed 2016-06-04 12:56:00 +10:00
690ddc268b logic fix 2016-06-04 12:51:49 +10:00
42cec9d87f logic fix 2016-06-04 12:51:28 +10:00
c4b23351ab update debug and formatting 2016-06-04 12:17:59 +10:00
431c0d7eb1 formatting 2016-06-04 10:47:18 +10:00
9f648c755d remove some unnecessary logging 2016-06-04 10:43:42 +10:00
450acf310b bugfix 2016-06-04 10:37:35 +10:00
d7e321b8a6 fix 2016-06-04 10:32:38 +10:00
a3a3cb29fa more debug 2016-06-04 10:27:17 +10:00
8ddbce54c1 possible fixes 2016-06-04 10:23:23 +10:00
004123a9e5 debug 2016-06-04 10:14:55 +10:00
ab2927844a some debugging 2016-06-04 10:07:07 +10:00
de0620fd0a bugfixes 2016-06-04 10:04:24 +10:00
aabd216aed fix 2016-06-04 09:57:14 +10:00
a8a9c5c43e travel form fixes 2016-06-04 09:56:34 +10:00
Nathan Coad
cffd8836da add missing comma 2016-06-03 15:18:51 +10:00
Nathan Coad
ce8bfedda1 add more preselection messages 2016-06-03 15:17:38 +10:00
Nathan Coad
48d2c4ad32 js fix 2016-06-03 15:05:11 +10:00
Nathan Coad
875fa6e839 js change 2016-06-03 14:59:28 +10:00
Nathan Coad
56054b763a update js to add/remove selected class 2016-06-03 13:31:08 +10:00
Nathan Coad
4eaf4a3450 fix 2016-06-03 13:22:25 +10:00
Nathan Coad
b52e63fe15 remove unnecessary linebreak 2016-06-03 13:21:31 +10:00
Nathan Coad
e37a259c72 formatting tweaks 2016-06-03 13:19:49 +10:00
Nathan Coad
0abdebe3bd tweak to html formatting 2016-06-03 13:15:35 +10:00
Nathan Coad
207c6212e5 update to avoid placeholder class in t() 2016-06-03 13:14:10 +10:00
Nathan Coad
940329bdd7 add some user feedback to ajax result 2016-06-03 13:11:03 +10:00
Nathan Coad
17076469de minor updates 2016-06-03 13:05:05 +10:00
Nathan Coad
a2a81303be bugfix 2016-06-03 12:58:20 +10:00
Nathan Coad
262340d866 minor tweaks 2016-06-03 12:57:12 +10:00
Nathan Coad
9f02b2de6b formatting fixes 2016-06-03 12:05:12 +10:00
Nathan Coad
ae79dbbc51 fix bug 2016-06-03 11:44:45 +10:00
Nathan Coad
c1d4164f81 more generic js 2016-06-03 11:38:11 +10:00
Nathan Coad
af1aaa7e81 fix stupidity 2016-06-03 11:33:37 +10:00
Nathan Coad
fcfbb6c885 fix 2016-06-03 11:33:01 +10:00
Nathan Coad
59f30c70d7 test more generic js function 2016-06-03 11:31:21 +10:00
Nathan Coad
fd084499b4 add test 2016-06-03 11:17:32 +10:00
Nathan Coad
8b31d1bebf js 2016-06-03 11:14:11 +10:00
Nathan Coad
1a519c1ee7 js 2016-06-03 11:09:23 +10:00
Nathan Coad
bfc1e642ab js test 2016-06-03 11:01:54 +10:00
Nathan Coad
d3ef2572a1 js test 2016-06-03 10:58:32 +10:00
Nathan Coad
8c6c935233 fix 2016-06-03 10:50:04 +10:00
Nathan Coad
4e4fda63f1 test 2016-06-03 10:48:51 +10:00
Nathan Coad
4f81f56c75 fix 2016-06-03 10:46:33 +10:00
Nathan Coad
6c1eb2528b js test 2016-06-03 10:28:45 +10:00
Nathan Coad
cf636af9fe add id to hidden form element 2016-06-03 09:53:05 +10:00
Nathan Coad
7974d9be3f fix 2016-06-03 09:47:45 +10:00
Nathan Coad
207f1f10da typo 2016-06-03 09:46:46 +10:00
Nathan Coad
747d1bbc0b work on dynamic form for manual emails 2016-06-03 09:45:16 +10:00
71d37a3bba pseudo code for dynamic manual email page 2016-06-03 08:02:54 +10:00
8a6681d922 manual email formatting 2016-06-02 10:48:25 +10:00
945a6b77f6 manual email preselection updates 2016-06-02 10:46:26 +10:00
e5322da7fb Add some descriptions to manual email preselections 2016-06-02 10:42:24 +10:00
a5fc4f9f50 Add booked-in filter for manual emails 2016-06-02 09:52:51 +10:00
66b71fc8ab remove some unnecessary debug statements 2016-06-01 22:32:09 +10:00
deed7bfb5f update _booking_node_create_mysqlview() 2016-06-01 22:29:00 +10:00
b9c032558e fix error handling 2016-06-01 22:20:18 +10:00
647853326c remove unnecessary call to _booking_get_person_fields() 2016-06-01 22:18:39 +10:00
243a7691b6 tidy up sqlview error handling 2016-06-01 22:17:05 +10:00
2d21af7d2f improve exception handling 2016-06-01 22:13:28 +10:00
449605a67d sql exception handling 2016-06-01 22:11:53 +10:00
5443d6377b description update 2016-06-01 22:09:06 +10:00
03d8681c55 updates to travel form and add calls to _booking_node_create_mysqlview 2016-06-01 22:07:48 +10:00
a01096d1a5 minor tweaks 2016-06-01 19:11:10 +10:00
3f5f80c308 description 2016-05-31 19:24:30 +10:00
c67778b652 logic fixes 2016-05-31 19:23:45 +10:00
d3f8ca0039 fix for no view existing already 2016-05-31 19:03:39 +10:00
8f2c8fe32a prepare for release 2016-05-31 18:55:05 +10:00
1c47838b73 fix 2016-05-31 18:44:10 +10:00
ff90039ed9 fix 2016-05-31 18:42:12 +10:00
8ecef65d38 fix 2016-05-31 18:41:02 +10:00
a82e6baa42 more debugging 2016-05-31 18:34:53 +10:00
aec30aabd2 bugfix 2016-05-31 18:30:50 +10:00
03a184625c bugfix 2016-05-31 18:30:22 +10:00
e887776ce5 debug 2016-05-31 18:28:54 +10:00
333cfa38c4 add logistics custom emails 2016-05-31 18:21:05 +10:00
a7f474ec56 convert travel page to full html text 2016-05-31 17:44:45 +10:00
4baa283539 fix 2016-05-31 17:29:31 +10:00
d783b24aed Merge branch 'master' of gitlab.coadcorp.com:drupal/booking 2016-05-31 17:26:56 +10:00
784fbf5351 updates 2016-05-31 17:25:31 +10:00
03fc848ec9 updates 2016-05-31 17:25:18 +10:00
7c4deaa502 fix fieldset 2016-05-31 17:21:07 +10:00
ca2764317b re-order text definition fields, change travel form to full html 2016-05-31 17:19:25 +10:00
335902e40f include new file 2016-05-31 17:11:12 +10:00
cda81990ee rearrange booking module configuration 2016-05-31 17:10:10 +10:00
02deeef731 split up some of the email functions for easier management 2016-05-31 17:06:27 +10:00
071ccba847 adjust _booking_get_person_fields() for sql view 2016-05-27 17:47:40 +10:00
910d74f905 fix quotes 2016-05-27 17:46:34 +10:00
ee4b273c8a improve debug messages 2016-05-27 17:45:45 +10:00
2ae35dd927 add call to _booking_node_create_mysqlview() in studygroup modification admin form 2016-05-27 17:40:48 +10:00
368d5d6555 call _booking_node_create_mysqlview when setting values via admin page 2016-05-27 17:30:04 +10:00
7336f4d351 use mysql view for loading nodes 2016-05-27 15:28:18 +10:00
c707f90c97 change to node load 2016-05-27 10:51:49 +10:00
e236d67c3f fix 2016-05-27 09:23:05 +10:00
48f5b4aa0b initial work on mysql view 2016-05-27 09:15:04 +10:00
df87648071 debug 2016-05-27 08:52:42 +10:00
04bbca85bb debugging 2016-05-27 08:32:40 +10:00
fbd33d1afc remove unworkable ajax tableselect code 2016-05-26 23:26:33 +10:00
d0946396b8 add default values for travel tokens even if that feature is not enabled 2016-05-26 23:15:25 +10:00
f446a7bf05 change path 2016-05-26 22:58:38 +10:00
fef0469144 re-enable option 2016-05-26 22:57:52 +10:00
a1b6ebc381 change manual email page to a form 2016-05-26 22:55:43 +10:00
369157fc9a test 2016-05-26 22:51:38 +10:00
84deb85c82 test 2016-05-26 22:50:44 +10:00
072c043ea0 test 2016-05-26 22:28:02 +10:00
8c43c3debe test 2016-05-26 22:26:33 +10:00
b184847b21 debug 2016-05-26 22:22:37 +10:00
3aa87394f5 test 2016-05-26 22:18:40 +10:00
e06552e3e4 fix 2016-05-26 22:16:30 +10:00
7c13255859 tweaks 2016-05-26 22:15:46 +10:00
5427bd6020 try hard coding preselection types for manual email form 2016-05-26 22:13:08 +10:00
7beffef6a9 undo test 2016-05-26 16:01:48 +10:00
44927ead8b test 2016-05-26 16:00:43 +10:00
ade8355721 test css per column 2016-05-26 15:55:36 +10:00
32cbbf1fc9 give up 2016-05-26 14:06:57 +10:00
f97f7d927b multiple 2016-05-26 14:02:29 +10:00
2cce280d8a add form_process_tableselect 2016-05-26 14:01:09 +10:00
0299adc9a0 test 2016-05-26 13:59:24 +10:00
b7e7f77e9a add ['new'] 2016-05-26 13:57:33 +10:00
7f4f3ff411 test 2016-05-26 13:56:00 +10:00
235e03a1ab test 2016-05-26 13:50:27 +10:00
78eed38378 test 2016-05-26 13:49:37 +10:00
d63ac9f570 remove replace ajax 2016-05-26 13:48:07 +10:00
edccce94a2 test more 2016-05-26 13:46:52 +10:00
083fd5aa08 add #value 2016-05-26 13:31:31 +10:00
8cde6fcba0 add caching stuff 2016-05-26 13:29:52 +10:00
c98ae4d095 test more 2016-05-26 13:27:34 +10:00
ccb9eb7c73 test again 2016-05-26 13:25:00 +10:00
1444a73331 test 2016-05-26 13:23:52 +10:00
c9e7d2dc33 another thing 2016-05-26 13:15:14 +10:00
f0b4e2d310 fix 2016-05-26 13:11:53 +10:00
b5f46b39b6 try another thing 2016-05-26 13:10:46 +10:00
112a29a492 give up on ajax selection of checkboxes 2016-05-26 12:51:40 +10:00
dca0c2194d test again 2016-05-26 12:45:50 +10:00
37b9a202c1 test 2016-05-26 12:41:02 +10:00
30f6a67954 workaround attempt 2016-05-26 12:37:40 +10:00
2b64a5f511 remove form_process_tableselect as a test 2016-05-26 12:16:18 +10:00
673ba97ea9 test default value 2016-05-26 12:11:55 +10:00
c558d2e626 making progress 2016-05-26 12:06:38 +10:00
c6e988945a recreate tableselect completely 2016-05-26 12:02:31 +10:00
d02a367648 test 2016-05-26 11:59:35 +10:00
3dd0f58a9b debug 2016-05-26 11:57:08 +10:00
f6991f9a6b new approach 2016-05-26 11:53:52 +10:00
f7f7e5fedc remove form_builder 2016-05-26 11:44:01 +10:00
ebe5dcb939 new test again 2016-05-26 11:42:03 +10:00
b30b0c9e89 new test 2016-05-26 11:39:55 +10:00
ccaa107103 test again again 2016-05-26 11:37:56 +10:00
ec6971d42a test again 2016-05-26 11:36:40 +10:00
3f52d241cf test 2016-05-26 11:32:46 +10:00
8b208a5fdb fix 2016-05-26 11:24:46 +10:00
fa969ee4a0 fix function call 2016-05-26 11:22:04 +10:00
a9d35ca97f try again 2016-05-26 11:20:17 +10:00
99e45f86a3 new approach 2016-05-26 11:11:46 +10:00
e695c26e78 fix typo 2016-05-26 11:00:30 +10:00
c03203bec6 try removing old tableselect first 2016-05-26 10:57:33 +10:00
dd780489ec back to basics 2016-05-26 10:53:55 +10:00
2730223507 don't inspect drupal_render output 2016-05-26 10:43:53 +10:00
f4444bb341 test 2016-05-26 10:41:50 +10:00
7adfffb739 debug 2016-05-26 10:35:47 +10:00
7c7310460c back to [new] 2016-05-26 10:32:26 +10:00
925be26646 more testing 2016-05-26 10:25:39 +10:00
31749b5a2c overwrite existing table 2016-05-26 10:24:13 +10:00
4d0c6c8186 missing bracket 2016-05-26 10:14:09 +10:00
43a8adbe20 more debug 2016-05-26 10:13:32 +10:00
7d03689695 add form builder 2016-05-26 10:10:15 +10:00
43558a4771 reference further down 2016-05-26 10:08:34 +10:00
08212c03ef debugging 2016-05-26 09:57:09 +10:00
c2cba77dad test 2016-05-26 09:55:21 +10:00
e46996adc1 fix incorrect reference 2016-05-26 09:45:46 +10:00
cf86228bfd rearrange caching 2016-05-26 09:42:21 +10:00
5fa185af69 comment out 2016-05-26 09:40:15 +10:00
64509f414f change cache code 2016-05-26 09:39:23 +10:00
25ceaa7e62 more debug statements 2016-05-26 09:34:38 +10:00
bde2f3800e some debugging 2016-05-26 09:30:19 +10:00
563a41a948 test 2016-05-26 09:26:21 +10:00
7a08abe8ee more testing 2016-05-26 09:23:49 +10:00
4ab03493d5 fix 2016-05-26 09:18:33 +10:00
65e29b0be2 ajax test 2016-05-26 09:18:04 +10:00
148a6be855 undo debug since it was unnecessary 2016-05-25 23:41:59 +10:00
e4f07d47e4 debug 2016-05-25 23:37:20 +10:00
fcbd24851e default email type 2016-05-25 23:30:08 +10:00
0906291040 logic 2016-05-25 23:28:50 +10:00
1ee1435b15 fix logic 2016-05-25 23:27:58 +10:00
af5e76f38e default value test 2016-05-25 23:26:42 +10:00
01fe861663 test 2016-05-25 23:24:02 +10:00
62454e55f2 moar tweaks 2016-05-25 23:13:04 +10:00
79a3e536d1 more css tweaks 2016-05-25 23:11:34 +10:00
f80a12a299 css test 2016-05-25 23:07:19 +10:00
6242224d36 add welfare css 2016-05-25 23:06:15 +10:00
ca14f58237 change class 2016-05-25 23:05:23 +10:00
78eb0a2b24 try using class instead of id 2016-05-25 23:04:17 +10:00
ae609f28da fix inverted logic 2016-05-25 23:01:06 +10:00
62ed20a354 add css 2016-05-25 23:00:30 +10:00
89460e6157 add highlighting to manual email page for welfare cases 2016-05-25 22:58:22 +10:00
691e1feeef Tidy up formatting 2016-05-25 11:25:04 +10:00
e02d863833 Code formatting fix 2016-05-25 11:20:35 +10:00
bd665d6110 Add travel-form enabled check to travel form page 2016-05-25 11:17:17 +10:00
4d3bcb4949 description update 2016-05-24 22:19:10 +10:00
2e09ca1814 update logic for travel form showing bf/gf field 2016-05-24 22:14:46 +10:00
1674c5242f bug 2016-05-19 22:20:46 +10:00
c230ea32da bug 2016-05-19 22:19:40 +10:00
929983acaa debugging 2016-05-19 22:17:14 +10:00
d7108b5a71 fix dereference 2016-05-19 22:15:54 +10:00
eced3d39bc use array instead of stdClass 2016-05-19 22:14:02 +10:00
abd4853ff5 bug fix 2016-05-19 22:13:08 +10:00
9b431c6ee3 start making csv import/export more dynamic 2016-05-19 22:09:03 +10:00
53 changed files with 11514 additions and 5372 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
images/Thumbs.db

View File

@@ -1 +1,18 @@
Drupal 7 module for managing event bookings.
Drupal 7 module for managing event bookings. Originally designed for use with the biennial Christadelphian event known as Study Week.
## Pre-installation
Before installation, download and install the following pre-requisite modules:
- [libraries](http://drupal.org/project/libraries) module
- [token](http://drupal.org/project/token) module
- [date](http://drupal.org/project/date) module
- [mimemail](http://drupal.org/project/mimemail) module
- [mailsystem](http://drupal.org/project/mailsystem) module
If you plan to use Stripe for payment integration, download the [Stripe API Library for PHP](https://github.com/stripe/stripe-php) and install in your sites libraries folder (usually sites/all/libraries). The folder should be renamed to stripe (ie sites/all/libraries/stripe/lib/Stripe.php).
## Installation
- Clone (or download & unpack) this module into your site's module directory (usually sites/all/modules)
- Enable the booking module, and visit the [configuration page](http://your.site.com/admin/config/booking/general) to set initial values and save prior to using module
## Configuration
In addition to the main configuration page, you will need to set up [text definitions](http://your.site.com/admin/config/booking/text) for various built-in pages, as well as update [email definitions](http://your.site.com/admin/config/booking/emails) for automatically generated emails.

View File

@@ -0,0 +1,48 @@
<?php
// @deprecated
// Use MimeMail module instead of this class
// Since this class doesn't handle attaching files
/**
* Implements MailSystemInterface
* Taken from http://www.ardoubleyou.com/blog/how-programmatically-send-e-mail-using-html-and-text-content-type-drupal-7
*/
class BookingMailSystem implements MailSystemInterface {
/**
* Concatenate and wrap the e-mail body for plain-text mails
* @param $message
* A message array, as described in hook_mail_alter().
*
* @return
* The formatted $message
*/
public function format(array $message) {
$message['body'] = implode("\n\n", $message['body']);
//watchdog('booking_debug', "<pre>BookingMailSystem format:\n@info</pre>", array('@info' => print_r( $message, true)));
return $message;
}
/**
* Send an e-mail message, using Drupal variables and default settings.
* @see drupal_mail*()
* @param $message
* A message array, as described in hook_mail_alter()
* @return
* TRUE if the mail was successfully accepted, otherwise FALSE
*/
public function mail(array $message) {
$mimeheaders = array();
foreach($message['headers'] as $name => $value) {
$mimeheaders[] = $name . ': ' . mime_header_encode($value);
}
$line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
$mail = mail(
$message['to'],
mime_header_encode($message['subject']),
preg_replace('@\r?\n@', $line_endings, $message['body']),
join("\n", $mimeheaders)
);
//watchdog('booking_debug', "<pre>BookingMailSystem mail:\n@info</pre>", array('@info' => print_r( $mail, true)));
return $mail;
}
}

View File

@@ -4,16 +4,27 @@
* The administration menu implementations for the booking module configuration pages
*/
function booking_admin()
{
function booking_admin() {
$form = array();
//regenerate all our menu hooks when loading this form
menu_rebuild();
$form = array();
//create the mysql view booking_person_view if necessary
try {
$sqlview_check = db_query("SELECT * FROM {booking_person_view}")->fetchAssoc();
watchdog('booking_debug', "<pre>SQL View booking_person_view check\n@info</pre>", array('@info' => print_r( $sqlview_check, true)));
}
catch (Exception $e) {
watchdog('booking_debug', "<pre>SQL View booking_person_view check does not exist\n@info</pre>", array('@info' => $e->getMessage()));
_booking_node_create_mysqlview();
}
//form commences here
$form['email'] = array(
'#type' => 'fieldset',
'#title' => 'Email Addresses'
'#title' => 'Email Addresses',
'#collapsible' => TRUE,
);
$form['email']['booking_from_email'] = array(
@@ -43,17 +54,27 @@ function booking_admin()
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from')))
'#default_value' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from'))),
);
$form['email']['booking_logistics_email'] = array(
'#type' => 'textfield',
'#title' => t('Logistics Email Address'),
'#description' => t("The email address used for logistics information."),
'#description' => t("The email address used for logistics information like travel forms etc."),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => variable_get('booking_logistics_email', variable_get('site_mail', ini_get('sendmail_from')))
'#default_value' => variable_get('booking_logistics_email', variable_get('site_mail', ini_get('sendmail_from'))),
);
$form['email']['booking_enable_html_mail'] = array(
'#type' => 'radios',
'#title' => t('Enable html emails?'),
'#description' => t('Turn this feature on for html based emails, otherwise plaintext emails will be used. HTML based emails will require a custom template file to be defined.<br /><strong>WARNING: This will reset all existing mail definitions.</strong> Take care before changing this value.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_html_mail', 0),
);
$form['email']['booking_custom_email_count'] = array(
'#type' => 'textfield',
@@ -63,10 +84,20 @@ function booking_admin()
'#maxlength' => 3,
'#default_value' => variable_get('booking_custom_email_count', '5')
);
$form['email']['booking_email_allowed_attachments'] = array(
'#type' => 'textfield',
'#title' => t('Allowed email attachments'),
'#description' => t("File extensions to allow as email attachments for the manual email page."),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => variable_get('booking_email_allowed_attachments', 'pdf docx'),
);
$form['attendee'] = array(
'#type' => 'fieldset',
'#title' => 'Attendee restrictions'
'#title' => 'Attendee restrictions',
'#collapsible' => TRUE,
);
$form['attendee']['booking_max_dob'] = array(
@@ -112,18 +143,22 @@ function booking_admin()
$form['paypal'] = array(
'#type' => 'fieldset',
'#title' => 'Paypal Settings'
'#title' => 'Paypal Settings',
'#collapsible' => TRUE,
//'#collapsed' => TRUE,
);
/*
$form['paypal']['booking_use_paypal'] = array(
'#type' => 'radios',
'#title' => t('Use Paypal?'),
'#description' => t('Select whether to use paypal for automatic payment handling, or process payments manually.'),
'#title' => t('Use Paypal? (DEPRECATED)'),
'#description' => t('Select whether to use paypal for automatic payment handling, or process payments manually. This option is now deprecated. Use the payment processor option below instead.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_use_paypal', 0)
);
*/
$form['paypal']['booking_paypal_account'] = array(
'#type' => 'textfield',
'#title' => t('Specify Paypal Account Address'),
@@ -165,9 +200,93 @@ function booking_admin()
'#description' => 'Percentage of transaction charged as paypal fee for transactions that include currency conversion, currently 3.6% in Australia'
);
//Stripe Settings
$form['stripe'] = array (
'#type' => 'fieldset',
'#title' => 'Stripe Settings',
'#collapsible' => TRUE,
//'#collapsed' => TRUE,
);
$explanation_text = t('<p>Verify your country supports stripe at <a href="https://stripe.com/global">the stripe website</a>.</p>' .
'<p>Register an account at stripe.com and visit <a href="https://dashboard.stripe.com/account/apikeys">the API keys page</a>, then copy your API keys here.</p>');
$form['stripe']['explanation-text'] = array(
'#type' => 'container',
'#children' => $explanation_text,
);
$form['stripe']['booking_stripe_test_secret_key'] = array (
'#type' => 'textfield',
'#title' => t('Specify Stripe Test Secret Key'),
'#default_value' => variable_get('booking_stripe_test_secret_key', ''),
'#description' => '(Secret API key)',
);
$form['stripe']['booking_stripe_test_public_key'] = array (
'#type' => 'textfield',
'#title' => t('Specify Stripe Test Public Key'),
'#default_value' => variable_get('booking_stripe_test_public_key', ''),
'#description' => '(Public API key)',
);
$form['stripe']['booking_stripe_live_secret_key'] = array (
'#type' => 'textfield',
'#title' => t('Specify Stripe Live Secret Key'),
'#default_value' => variable_get('booking_stripe_live_secret_key', ''),
'#description' => '(Secret API key)',
);
$form['stripe']['booking_stripe_live_public_key'] = array (
'#type' => 'textfield',
'#title' => t('Specify Stripe Live Public Key'),
'#default_value' => variable_get('booking_stripe_live_public_key', ''),
'#description' => '(Public API key)',
);
$form['stripe']['booking_stripe_testmode'] = array (
'#type' => 'radios',
'#title' => t('Stripe Test mode'),
'#description' => t('When in test mode, payments will use test api keys which will not make any charges to cards. Leave this as off unless doing testing.'),
'#options' => array (0 => t('Off'), t('On')),
'#default_value' => variable_get('booking_stripe_testmode', 0),
);
$form['stripe']['booking_stripe_transaction_fee_fixedcost'] = array (
'#type' => 'textfield',
'#title' => t('Stripe fixed cost transaction fee'),
'#default_value' => variable_get('booking_stripe_transaction_fee_fixedcost', '0.3'),
'#field_prefix' => '$',
'#size' => 5,
'#description' => 'Transaction fee is currently $0.3 AUD and is added before the percentage fee is applied.',
);
$form['stripe']['booking_stripe_transaction_fee_percentage'] = array (
'#type' => 'textfield',
'#title' => t('Stripe Percentage Transaction Fee'),
'#default_value' => variable_get('booking_stripe_transaction_fee_percentage', '1.75'),
'#field_prefix' => '%',
'#size' => 5,
'#description' => 'Percentage of transaction charged as stripe fee, currently 1.75% in Australia',
);
$form['stripe']['booking_stripe_transaction_fee_percentage_intl'] = array (
'#type' => 'textfield',
'#title' => t('Stripe Percentage Transaction Fee (International)'),
'#default_value' => variable_get('booking_stripe_transaction_fee_percentage_intl', '2.9'),
'#field_prefix' => '%',
'#size' => 5,
'#description' => 'Percentage of transaction charged as stripe fee for transactions that include currency conversion, currently 2.9% in Australia. This fee also applies to American Express cards.',
);
$form['stripe']['booking_stripe_logo'] = array (
'#type' => 'textfield',
'#title' => t('Logo URL for Stripe Checkout Form'),
'#description' => 'Enter the full URL to a logo file that will be used on the stripe checkout form.<br />The recommended minimum size is 128x128px. The supported image types are: .gif, .jpeg, and .png.',
'#default_value' => variable_get('booking_stripe_logo', 'https://stripe.com/img/documentation/checkout/marketplace.png'),
);
//feature settings
$form['features'] = array(
'#type' => 'fieldset',
'#title' => 'Enable/Disable Features'
'#title' => 'Enable/Disable Features',
'#collapsible' => TRUE,
);
$form['features']['booking_payment_processor'] = array (
'#type' => 'radios',
'#title' => t('Select Payment Processor to use'),
'#description' => t('Select between Paypal, Stripe or Manaul Payment to use for processing payments.'),
'#options' => array (0 => t('Paypal'), t('Stripe'), t('Manual Payments')),
'#default_value' => variable_get('booking_payment_processor', 0),
);
$form['features']['booking_enable_roomallocations'] = array(
'#type' => 'radios',
@@ -221,6 +340,30 @@ function booking_admin()
'#default_value' => variable_get('booking_publish_readinggroups', 0)
);
$form['features']['booking_friendly_csv_groupnames'] = array(
'#type' => 'radios',
'#title' => t('Use human-friendly study group names in CSV export?'),
'#description' => t('Select whether to use descriptions for study group columns when exporting CSV. If No, internal database field names are used.'),
'#options' => array(0 => t('No'), t('Yes')),
'#default_value' => variable_get('booking_friendly_csv_groupnames', 0),
);
$form['features']['booking_studygroup_csv_ages'] = array(
'#type' => 'radios',
'#title' => t('Include ages in study group CSV export?'),
'#description' => t('Select whether to inclde ages for attendees when exporting study groups to CSV.'),
'#options' => array(0 => t('No'), t('Yes')),
'#default_value' => variable_get('booking_studygroup_csv_ages', 0),
);
$form['features']['booking_enable_emoji_removal'] = array(
'#type' => 'radios',
'#title' => t('Remove emoji from user input?'),
'#description' => t('Select whether to strip emoji from user input before saving to database. Useful if mysql does not support utf8mb4.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_emoji_removal', 1)
);
$form['misc'] = array(
'#type' => 'fieldset',
'#title' => 'Configuration Options'
@@ -280,7 +423,8 @@ function booking_admin()
$form['regn_options'] = array(
'#type' => 'fieldset',
'#title' => 'Registration Form Configuration'
'#title' => 'Registration Form Configuration',
'#collapsible' => TRUE,
);
$form['regn_options']['booking_default_country'] = array(
@@ -343,17 +487,6 @@ function booking_admin()
)
);
$form['regn_options']['booking_dependant_children_text'] = array(
'#type' => 'radios',
'#title' => t('Ask whether a couple has dependant children attending?'),
'#description' => t('Select whether to ask about dependant children of married couples in the registration form'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_ask_dependant_children', 0)
);
$form['regn_options']['booking_enable_medicare'] = array(
'#type' => 'radios',
'#title' => t('Enable Medicare requirement?'),
@@ -392,10 +525,10 @@ function booking_admin()
),
'#default_value' => variable_get('booking_enable_tshirts', 0)
);
/*
$form['regn_options']['booking_enable_passport'] = array(
'#type' => 'radios',
'#title' => t('Enable passport information?'),
'#title' => t('Enable passport information? (DEPRECATED)'),
'#description' => t('Select whether to include passport details in the booking form.'),
'#options' => array(
0 => t('No'),
@@ -403,6 +536,7 @@ function booking_admin()
),
'#default_value' => variable_get('booking_enable_passport', 0)
);
*/
$form['regn_options']['booking_enable_helpareas'] = array(
'#type' => 'radios',
'#title' => t('Enable help area questions?'),
@@ -429,6 +563,7 @@ function booking_admin()
)
)
);
$form['regn_options']['booking_enable_skills'] = array(
'#type' => 'radios',
'#title' => t('Enable special skills information?'),
@@ -502,9 +637,89 @@ function booking_admin()
)
);
$form['regn_options']['booking_enable_earlyaccess_codes'] = array(
'#type' => 'radios',
'#title' => t('Allow early access to registration form with unique code?'),
'#description' => t('Select whether to enable the feature that will allow early registrations with a unique code. Turning on this feature will allow registrations immediately, regardless of event registration start date.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_earlyaccess_codes', 0)
);
$form['regn_options']['booking_earlyaccess_codes_count'] = array(
'#type' => 'textfield',
'#title' => t('Number of early access codes'),
'#description' => t("Set to the number of early access codes to generate. You will need to visit the !configuration to actually generate these codes.",
array('!configuration' => l('Configuration Page', 'admin/config/booking/earlyaccess'))),
'#size' => 3,
'#maxlength' => 3,
'#default_value' => variable_get('booking_earlyaccess_codes_count', '0'),
);
$form['regn_options']['booking_enable_songchoice'] = array(
'#type' => 'radios',
'#title' => t('Enable attendee to specify song choice?'),
'#description' => t('Select whether to include questions about song choice in the booking form.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_songchoice', 0)
);
$form['regn_options']['booking_require_songchoice'] = array(
'#type' => 'radios',
'#title' => t('Require attendees to enter a song?'),
'#description' => t('Select whether to require attendees to enter a song choice for the week when they register. Doesn\'t have any effect if song choice is not enabled above.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_require_songchoice', 0)
);
$form['regn_options']['booking_enable_freestyle'] = array(
'#type' => 'radios',
'#title' => t('Enable attendee to enter freestyle text'),
'#description' => t('Select whether to include freestyle text field in the booking form.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_freestyle', 0)
);
$form['regn_options']['booking_require_freestyle'] = array(
'#type' => 'radios',
'#title' => t('Require attendees to enter some freestyle text?'),
'#description' => t('Select whether to require attendees to enter some freestyle text when they register. Doesn\'t have any effect if freestyle text is not enabled above.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_require_freestyle', 0)
);
$form['regn_options']['booking_enable_previous_studyweeks'] = array(
'#type' => 'radios',
'#title' => t('Ask attendee to specify previous study weeks?'),
'#description' => t('Select whether to ask the attendee how many study weeks they\'ve been to previously in the booking form.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_enable_previous_studyweeks', 0)
);
$form['regn_options']['booking_require_previous_sw'] = array(
'#type' => 'radios',
'#title' => t('Require attendees to select number of previous study weeks?'),
'#description' => t('Select whether to require attendees to choose the number of study weeks they previously attended. Doesn\'t have any effect if previous studyweek question is not enabled above.'),
'#options' => array(
0 => t('No'),
t('Yes')
),
'#default_value' => variable_get('booking_require_previous_sw', 0)
);
$form['management'] = array(
'#type' => 'fieldset',
'#title' => 'Data Management Options'
'#title' => 'Data Management Options',
'#collapsible' => TRUE,
);
$form['management']['booking_csv_exclude_fields'] = array(
'#type' => 'textfield',
@@ -522,7 +737,62 @@ function booking_admin()
'#size' => 150,
'#maxlength' => 2000
);
return system_settings_form($form);
$booking_view_fields = _booking_get_person_fields();
$form['management']['booking_export_include_fields_dynamic'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Not In Use - Select database fields'),
'#description' => t('Select database fields to export to CSV. Ensure you hold down control/command when selecting multiple options.'),
'#options' => $booking_view_fields,
'#default_value' => variable_get('booking_export_include_fields_dynamic', ''),
);
$form['management']['booking_import_include_fields_dynamic'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Not In Use - Select database fields'),
'#description' => t('Select database fields to import from an uploaded CSV file. Ensure you hold down control/command when selecting multiple options.'),
'#options' => $booking_view_fields,
'#default_value' => variable_get('booking_import_include_fields_dynamic', ''),
);
$form['meta-tokens'] = array(
'#type' => 'fieldset',
'#title' => 'Meta Token Definitions',
'#collapsible' => TRUE,
);
$form['meta-tokens']['booking_studygroup_summary_li_text'] = array (
'#type' => 'textfield',
'#title' => t('Study Group Summary Format'),
'#default_value' => variable_get('booking_studygroup_summary_li_text',
'You are a <b>[meta-booking:studygroup-role]</b> for group <b>[meta-booking:studygroup-descrip]</b>, which will occur on [meta-booking:studygroup-weekday].' .
'<br /><b>[meta-booking:studygroup-explan]</b>'
),
'#description' => 'List element definition (using tokens) for token [booking:studygroup-summary], which is the study group summary in emails. ' .
'Note: Don\'t add the li tags, they will be added automatically.',
'#size' => 150,
'#maxlength' => 2000,
);
$form['meta-tokens']['booking_studygroup_leaderhelperpair_text'] = array (
'#type' => 'textfield',
'#title' => t('Leader/Helper Pair Format'),
'#default_value' => variable_get('booking_studygroup_leaderhelperpair_text',
'<b>[meta-booking:studygroup-role]</b> for <b>[meta-booking:studygroup-descrip]</b>. ' .
'Your [meta-booking:studygroup-otherrole] is <b>[meta-booking:studygroup-othername]</b>. ' .
'You can contact them on [meta-booking:studygroup-otherphone] or [meta-booking:studygroup-otheremail].'
),
'#description' => 'List element definition (using tokens) for token [booking:leaderhelper-pair], which is the study group leader/helper pair information in emails. ' .
'Note: Don\'t add the li tags, they will be added automatically.',
'#size' => 150,
'#maxlength' => 2000,
);
//return system_settings_form($form);
//make sure we update our custom sql view every time we change something on the admin page
$form = system_settings_form($form);
//$form['#submit'][] = '_booking_node_create_mysqlview';
return $form;
}
function booking_admin_validate($form, $form_state)

View File

@@ -1,19 +1,20 @@
<?php
// $Id: booking.confirm.inc,v 0.1 2011/07/12
/**
* Confirmation page for event registration
* Balance payment page for event registration
*/
function booking_balance_page() {
global $event;
$payment_processor_type = variable_get('booking_payment_processor', 0);
$output = "";
$waiting_list = False;
$already_paid = false;
$waiting_list = FALSE;
$already_paid = FALSE;
$paypal_form = "";
//verify that arg(1) is a uuid
if (! preg_match('/^[0-9A-Fa-f\-]+$/', arg(1))) {
//parameter from url is not what we were expecting
watchdog('booking', "Invalid token supplied to the balance payment page.");
drupal_set_message("Error: Invalid token supplied to the balance payment page. Please use the contact us form to let us know.", 'error', FALSE);
drupal_goto('<front>');
return "";
@@ -24,13 +25,22 @@ function booking_balance_page() {
//work out the node id from the session id
$query = db_select('booking_person', 'p');
$db_and = db_and()->condition('p.booking_eventid', $event->eid, '=')
->condition('p.booking_tempid', arg(1), '=');
$query->condition($db_and);
$query->fields('p', array('nid'));
$person = $query->execute()
->fetchObject();
/*
$query = db_select('booking_person', 'p');
$query->condition('p.booking_tempid', arg(1), '=')
->fields('p', array('nid'));
$person = $query->execute()
->fetchObject();
*/
if ($person)
{
if ($person) {
//load all the fields
$node = node_load($person->nid);
//calculate the invoice ID
@@ -38,6 +48,9 @@ function booking_balance_page() {
//maximum length for invoice id in paypal is 127 characters so truncate if necessary
$invoiceid = substr($invoiceid, 0, 126);
} else {
watchdog('booking', "<pre>Unmatched token supplied to the balance payment page:\n@info</pre>", array(
'@info' => print_r(arg(1), true)
));
drupal_set_message("Error: Invalid token supplied to the balance payment page. Please use the contact us form to let us know.", 'error', FALSE);
drupal_goto('<front>');
return "";
@@ -45,30 +58,32 @@ function booking_balance_page() {
//populate tokens and paypal form
$tokens = booking_define_personspecific_tokens($node);
//if paypal is enabled
if ($payment_processor_type == 0) {
$tokens['paypal-total-form'] = _booking_paypal_form($node, $invoiceid, $tokens['paypal-total-amount'], "Pay Balance");
//Calculate the amount outstanding
//watchdog('booking', 'Booking Balance form calculating amount owing');
//$amount_owing = _booking_amount_owing($person->nid);
}
//if stripe is enabled
elseif ($payment_processor_type == 1) {
$tokens['stripe-total-form'] = _booking_stripe_form($node, $invoiceid, $tokens['payment-required'], "Pay Balance");
}
//watchdog('booking_debug', "<pre>Balance page tokens:\n@info</pre>", array('@info' => print_r( $tokens, true)));
//If the amount outstanding is zero, then display information to that effect.
if ($tokens['paypal-total-amount'] == 0)
{
if ($tokens['payment-required'] == 0) {
$output = token_replace(variable_get('booking_regn_balance_page_paid'), $tokens);
}
else
{
else {
$output = token_replace(variable_get('booking_regn_balance_page'), $tokens);
//optional additional text for married people
if ($node->booking_married == 'Y')
if ($node->booking_married == 'Y') {
$output .= token_replace(variable_get('booking_regn_balance_married_text'), $tokens);
}
}
//put all the bits together
$return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output));
//$return_array[] = array('form' => $paypal_form);
//return the form
//return the page
return $return_array;
}

View File

@@ -10,6 +10,7 @@ function booking_confirm_page() {
$already_paid = false;
$paypal_form = "";
$uuid = arg(1);
$payment_processor_type = variable_get('booking_payment_processor', 0);
//verify that arg(1) is a uuid
if (! preg_match('/^[0-9A-Fa-f\-]+$/', $uuid)) {
@@ -32,6 +33,8 @@ function booking_confirm_page() {
if ($person) {
//load all the fields
$node = node_load($person->nid);
//watchdog('booking_debug', 'booking_confirm_page node: <pre>@info</pre>', array('@info' => print_r( $node, true)));
//maximum length for invoice id is 127 characters
$invoiceid = $person->nid . '_' . $node->booking_eventid . '_' . $node->booking_lastname . '-' . $node->booking_firstname;
$invoiceid = substr($invoiceid, 0, 126);
@@ -45,11 +48,18 @@ function booking_confirm_page() {
//populate tokens
$tokens = booking_define_personspecific_tokens($node);
//add in the paypal forms as tokens
//if paypal is enabled then add tokens for it
if ($payment_processor_type == 0) {
$tokens['paypal-deposit-form'] = _booking_paypal_form($node, $invoiceid, $tokens['paypal-deposit-amount'], "Pay Deposit");
$tokens['paypal-total-form'] = _booking_paypal_form($node, $invoiceid, $tokens['paypal-total-amount'], "Pay Full Amount");
//watchdog('booking', 'Paypal form "@info"', array ('@info' => var_export($tokens['paypal-total-form'], TRUE)));
}
//if stripe is enabled
elseif ($payment_processor_type == 1) {
//@todo confirm that the deposit amount is correct for a stripe deposit
$tokens['stripe-deposit-form'] = _booking_stripe_form($node, $invoiceid, $tokens['stripe-deposit-amount'], "Pay Deposit");
$tokens['stripe-total-form'] = _booking_stripe_form($node, $invoiceid, $tokens['payment-required'], "Pay Balance");
}
//check if this registration will be on the waiting list
if (_booking_check_bookings_full() == True || $node->booking_status == 2) {

View File

@@ -1,5 +1,34 @@
<?php
/**
* Helper function to provide a list of custom email types for editing/sending manually
*/
function _booking_custom_email_types() {
$email_options_array = array();
$email_options_array['NULL'] = "---";
$email_options_array['registration'] = 'Registration Successful Email';
$email_options_array['balance'] = 'Balance Outstanding Email';
$email_options_array['complete'] = 'Payment Complete Email';
$email_options_array['withdrawal'] = 'Withdrawal Processed Email';
$email_options_array['waitinglistpromotion'] = 'Position Available (Balance outstanding)';
$email_options_array['waitinglistpromotionfullypaid'] = 'Position Available (Fully Paid)';
$email_options_array['missedpayment'] = 'Missed Payment Email';
$email_options_array['initialtravelrequired'] = 'Initial Travel Form Required Email';
$email_options_array['remindertravelrequired'] = 'Reminder Travel Form Required Email';
$email_options_array['travelcomplete'] = 'Travel Form Complete Email';
//add in the custom email types
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++) {
$email_options_array['custom' . $i] = variable_get('booking_email_subject_custom' . $i, $event->booking_eventname . ' custom ' . $i);
}
//add in the custom email types from logistics
for ($i = 1; $i <= 5; $i++) {
$email_options_array['customlogistics' . $i] = variable_get('booking_email_subject_customlogistics' . $i,
$event->booking_eventname . ' logistics custom ' . $i) . " **Logistics**";
}
return $email_options_array;
}
/**
* Helper function to provide a list of options for the state field of the registration form
*/
@@ -101,26 +130,40 @@ function _get_tshirt_options() {
return $options_array;
}
/**
* Helper function to provide a list of options for the previous study week count field of the registration form
*/
function _get_previous_sw_options() {
$options_array = array();
$options_array[''] = '';
for ($i = 0; $i < 6; $i++) {
$options_array[$i] = $i;
}
return $options_array;
}
/**
* Helper function to look up description of studygroup role
* @param $input integer containing role id
* @return string for corresponding role
*/
function _booking_studygroup_role_lookup($input = NULL)
{
function _booking_studygroup_role_lookup($input = NULL) {
$role = array();
$role[] = t('No Role');
$role[] = t('Leader');
$role[] = t('Helper');
$role[] = t('Reserve Leader');
$role[] = t('Reserve Helper');
if ($input != NULL)
if ($input != NULL) {
return $role[$input];
else
}
else {
return $role;
}
}
/**
* Helper function to look up description of room location based on id
@@ -185,12 +228,12 @@ function _booking_readinggroup_colour_lookup($input = NULL)
$group[] = t('Maroon');
$group[] = t('Pink');
$group[] = t('Black');
$group[] = t('Checks');
$group[] = t('Yellow');
$group[] = t('Purple');
$group[] = t('White');
$group[] = t('Red');
$group[] = t('Orange');
$group[] = t('Checks');
$group[] = t('Green');
$group[] = t('Blue');
$group[] = t('Brown');

View File

@@ -1,7 +1,32 @@
#leader-row {background: #6495ED;}
#helper-row {background: #9dd781;}
#reserveleader-row {background: #d4dc5c;}
#new-group-row {border-top: thick double #ff0000;}
#leader-new-group-row {background: #6495ED; border-top: thick double #ff0000;}
#helper-new-group-row {background: #9dd781; border-top: thick double #ff0000;}
#reserveleader-new-group-row {background: #d4dc5c; border-top: thick double #ff0000;}
#reservehelper-row {background: #d4dc5c;}
/*
tr.leader-row.odd {background: #6495ED;}
tr.leader-row.even {background: #6495ED;}
tr.helper-row.odd {background: #9dd781;}
tr.helper-row.even {background: #9dd781;}
tr.reserveleader-row.odd {background: #d4dc5c;}
tr.reserveleader-row.even {background: #d4dc5c;}
tr.reservehelper-row.odd {background: #d4dc5c;}
tr.reservehelper-row.even {background: #d4dc5c;}
*/
#new-group-row {border-top: thick double black;}
#leader-new-group-row {background: #6495ED; border-top: thick double black;}
#helper-new-group-row {background: #9dd781; border-top: thick double black;}
#reserveleader-new-group-row {background: #d4dc5c; border-top: thick double black;}
#reservehelper-new-group-row {background: #d4dc5c; border-top: thick double black;}
/* test for email page*/
/* tr.normal-row.odd {} */
/* tr.normal-row.even {} */
tr.welfare-row.odd {background: #c3e06c;}
tr.welfare-row.even {background: #c3e06c;}
tr.flying-row.odd {background: #c3e06c;}
tr.flying-row.even {background: #e5f2c0;}
tr.accomm-row.odd {background: #ffb380;}
tr.accomm-row.even {background: #ffb380;}
div#booking_email_preselection_suffix_wrapper {
margin-bottom: 10px;
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* @file
* Admin pages for managing early access codes
*/
// @todo - list all early access codes for the current event, whether they're available, and who used them if not
/**
* Function to summarise information about early access codes
*/
function booking_earlyaccess_admin() {
global $event;
$output = "";
$rows = array();
$attributes = array('style' => 'max-width:60%', 'id' => 'sort-table');
$prefix = t("<h2>Early Access Codes</h2>");
$header = array(
'booking_earlyaccess_code' => array('data' => t('Code'), 'field' => 'c.booking_earlyaccess_code', 'sort' => 'asc'),
'booking_earlyaccess_code_avail' => array('data' => t('Available?'), 'field' => 'c.booking_earlyaccess_code_avail'),
'booking_firstname' => array('data' => t('First Name'), 'field' => 'p.booking_firstname'),
'booking_lastname' => array('data' => t('Last Name'), 'field' => 'p.booking_lastname'),
);
//get a list of all the early access codes for this event
$codelist_query = db_select('booking_earlyaccess_codes', 'c');
$codelist_query->leftJoin('booking_person', 'p', 'c.cid = p.booking_earlyaccess_code_id');
$codelist_query->condition('c.booking_eventid', $event->eid, '=')
->fields('c')
->fields('p')
->orderBy('cid');
$result = $codelist_query->execute();
//add results to array
foreach($result as $data) {
$rows[] = array(
'data' => array(
$data->booking_earlyaccess_code,
$data->booking_earlyaccess_code_avail == 'Y' ? 'Yes' : 'No',
$data->booking_firstname,
$data->booking_lastname,
),
);
}
//theme output
$output = array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'table' => array (
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#attributes' => $attributes,
//'#sticky' => FALSE,
)
);
//return markup array
return $output;
}
/**
* Function to generate early access codes for the current event
*/
function booking_earlyaccess_generate_codes() {
global $event;
$num_codes_to_add = 0;
$num_codes_available = 0;
$code_length = 7;
//determine number of currently available access codes for this event
$codecount_query = db_query("SELECT count(*) as num_codes FROM {booking_earlyaccess_codes} where booking_eventid = :eventid and booking_earlyaccess_code_avail = 'Y'",
array(':eventid' => $event->eid))
->fetchObject();
$num_codes_available = $codecount_query->num_codes;
//get the number of codes we need to have available from variable_get('booking_earlyaccess_codes_count')
$num_codes_to_add = variable_get('booking_earlyaccess_codes_count', 0) - $num_codes_available;
//add required number of codes to database table
watchdog('booking_debug', "Creating $num_codes_to_add early access codes.");
//use the multi-insert query type at https://drupal.org/node/310079
$insert_query = db_insert('booking_earlyaccess_codes')
->fields(array(
'booking_eventid',
'booking_earlyaccess_code',
'booking_earlyaccess_code_avail',
));
for ($i = 0; $i < $num_codes_to_add; $i++) {
$insert_query->values(array(
'booking_eventid' => $event->eid,
'booking_earlyaccess_code' => booking_getToken($code_length),
'booking_earlyaccess_code_avail' => 'Y',
));
}
$insert_query->execute();
return t("Created $num_codes_to_add early access codes.");
}
/**
* Function to generate csv of early access codes for the current event
*/
function booking_earlyaccess_csv_report() {
global $event;
$data = array();
$header_array = array();
//set options for the CSV file
$name = 'bookings-earlyaccesscodes-' . format_date(time(), 'custom', 'Y-m-d-His');
$filename = file_directory_temp() . '/' . $name;
$csv = '';
$delimiter = ',';
$enclosure = '"';
$encloseAll = true;
$nullToMysqlNull = true;
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
//get a list of all the early access codes for this event
$codelist_query = db_select('booking_earlyaccess_codes', 'c');
$codelist_query->condition('c.booking_eventid', $event->eid, '=')
->fields('c', array('booking_earlyaccess_code', 'booking_earlyaccess_code_avail'))
->orderBy('cid');
$result = $codelist_query->execute();
foreach ($result as $record) {
foreach ($record as $key => $value) {
$header_array[] = $key;
}
break;
}
//calculate the header row for CSV
$header = implode($delimiter, $header_array);
$csv .= $header . "\n";
//add the records
reset($result);
foreach ($result as $record) {
$output = array();
//each keypair in the record
foreach ($record as $key => $value) {
// Enclose fields containing $delimiter, $enclosure or whitespace
if ($encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $value ) ) {
$output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure;
}
else {
$output[] = $field;
}
}
$row = implode($delimiter, $output) . "\n";
$csv .= $row;
}
//output the CSV to the browser
drupal_add_http_header("Content-type", "application/octet-stream; charset=utf-8");
drupal_add_http_header("Content-Disposition", "attachment; filename=" . $name . ".csv");
print $csv;
exit(0);
}
/**
* Function to calculate unique code
* @see https://stackoverflow.com/questions/1846202/php-how-to-generate-a-random-unique-alphanumeric-string
* Requires PHP7
*/
function booking_getToken($length) {
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
$codeAlphabet.= "0123456789";
$max = strlen($codeAlphabet); // edited
if (!function_exists('random_int')) {
function random_int($min, $max) {
if (!function_exists('mcrypt_create_iv')) {
trigger_error(
'mcrypt must be loaded for random_int to work',
E_USER_WARNING
);
return null;
}
if (!is_int($min) || !is_int($max)) {
trigger_error('$min and $max must be integer values', E_USER_NOTICE);
$min = (int)$min;
$max = (int)$max;
}
if ($min > $max) {
trigger_error('$max can\'t be lesser than $min', E_USER_WARNING);
return null;
}
$range = $counter = $max - $min;
$bits = 1;
while ($counter >>= 1) {
++$bits;
}
$bytes = (int)max(ceil($bits/8), 1);
$bitmask = pow(2, $bits) - 1;
if ($bitmask >= PHP_INT_MAX) {
$bitmask = PHP_INT_MAX;
}
do {
$result = hexdec(
bin2hex(
mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
)
) & $bitmask;
} while ($result > $range);
return $result + $min;
}
}
for ($i=0; $i < $length; $i++) {
$token .= $codeAlphabet[random_int(0, $max-1)];
}
return $token;
}

594
booking.email_manually.inc Normal file
View File

@@ -0,0 +1,594 @@
<?php
/**
* Function to allow admin user to manually generate and send a workflow or custom email
*
* @param
* @return form render array
*/
function booking_manual_email_form($form, &$form_state)
{
global $event;
//see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios
/*
create hidden form element that we will populate with JSON data via ajax
create select element defining the pre-selections available
create submit button that calls ajax to update hidden form element, then calls ajax to check the checkboxes based on the hidden form element
info on turning JSON data back to array
http://stackoverflow.com/questions/29076219/javascript-storing-array-of-objects-in-hidden-field
ajax references:
http://www.maged.me/blog/drupal-7-execute-javascript-code-after-ajax-call
https://www.drupal.org/node/1028410
https://www.drupal.org/node/2046693
jquery to check the checkboxes:
http://jsfiddle.net/nanoquantumtech/dnhwz/
*/
$form = array();
$options = array();
$preselection_options = array();
$values = array();
$group_text = "";
$prefix = t("<p>Send a manual email to people registered for this event. ");
$prefix .= t("Click !workflow to update builtin-workflow emails, or click !custom to update custom email definitions.</p>",
array ('!workflow' => l('here', 'admin/config/booking/emails'), '!custom' => l('here', 'admin/config/booking/emails/definitions')));
$prefix .= t("<p>Highlighted rows have welfare requirements.</p>");
$email_options_array = array();
$email_options_array['NULL'] = "---";
$email_options_array['registration'] = 'Registration Successful Email';
$email_options_array['balance'] = 'Balance Outstanding Email';
$email_options_array['complete'] = 'Payment Complete Email';
$email_options_array['withdrawal'] = 'Withdrawal Processed Email';
$email_options_array['waitinglistpromotion'] = 'Position Available (Balance outstanding)';
$email_options_array['waitinglistpromotionfullypaid'] = 'Position Available (Fully Paid)';
$email_options_array['missedpayment'] = 'Missed Payment Email';
$email_options_array['initialtravelrequired'] = 'Initial Travel Form Required Email';
$email_options_array['remindertravelrequired'] = 'Reminder Travel Form Required Email';
$email_options_array['travelcomplete'] = 'Travel Form Complete Email';
$preselection_options['---'] = "---";
$preselection_options['notpaid'] = 'People who have not yet paid';
$preselection_options['bookedin'] = 'People who are booked-in';
$preselection_options['waitinglist'] = 'People on waiting list';
$preselection_options['unpaid'] = 'People booked-in with outstanding balance';
$preselection_options['refundreqd'] = 'Refund Required';
$preselection_options['notravelform'] = "People booked-in no travel form received";
$preselection_options['notravelforminclwaiting'] = "People booked-in/waiting no travel form received";
$preselection_options['leaderhelper'] = "Leaders/Helpers";
$preselection_options['readinggroup-leader'] = "Reading Group Leaders";
$header = array(
'booking_nid' => array('data' => t('Id'), 'field' => 'nid', 'sort' => 'asc'),
'booking_name' => array('data' => t('Name'), 'field' => 'booking_lastname'),
'booking_gender' => array('data' => t('Gender'), 'field' => 'booking_gender'),
'booking_email' => array('data' => t('Email'), 'field' => 'booking_email'),
'booking_state' => array('data' => t('State'), 'field' => 'booking_state'),
'booking_status' => array('data' => t('Status'), 'field' => 'booking_status'),
'amount_paid' => array('data' => t('Payment To Date'), 'field' => 'booking_amount_paid'),
'amount_reqd' => array('data' => t('Total Payment Required'), 'field' => 'booking_total_pay_reqd'),
'booking_fully_paid' => array('data' => t('Fully paid?'), 'field' => 'booking_payment_complete'),
'welfare_required' => array('data' => t('Welfare Required?'), 'field' => 'booking_welfare_required'),
);
//add in the custom email types
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++) {
$email_options_array['custom' . $i] = variable_get('booking_email_subject_custom' . $i, $event->booking_eventname . ' custom ' . $i);
}
//add in the custom email types from logistics
for ($i = 1; $i <= 5; $i++) {
$email_options_array['customlogistics' . $i] = variable_get('booking_email_subject_customlogistics' . $i,
$event->booking_eventname . ' logistics custom ' . $i) . " **Logistics**";
}
//attach css so we can customise colours for some people
$form['#attached']['css'] = array(
drupal_get_path('module', 'booking') . '/booking.css',
);
//attach js for dynamically setting checkboxes
$form['#attached']['js'][] = drupal_get_path("module", "booking")."/booking.js";
$form['pretext'] = array(
'#type' => 'container',
'#children' => $prefix,
);
//@todo add booking prefix
$form['email-type'] = array(
'#type' => 'select',
'#title' => t('Email Type'),
'#required' => TRUE,
'#default_value' => 'NULL',
'#options' => $email_options_array,
'#ajax' => array(
'event' => 'change',
'callback' => '_booking_email_get_preview_callback',
'wrapper' => 'booking_email_preview_wrapper',
),
);
$form['booking-email-default-ids'] = array (
'#type' => 'hidden',
'#value' => "[]",
'#prefix' => '<div id="booking_email_default_ids_wrapper">',
'#suffix' => '</div>',
'#attributes' => array('id' => 'booking_email_default_ids'),
);
$form['booking-email-preselection'] = array(
'#type' => 'select',
'#title' => t('Pre-select attendees from list'),
'#description' => t('Use this to select a large group of people based on pre-defined criteria.'),
'#options' => $preselection_options,
'#default_value' => '---',
'#suffix' => '<div id="booking_email_preselection_suffix_wrapper"></div>',
'#ajax' => array(
'event' => 'change',
'callback' => '_booking_email_get_default_selection_callback',
'wrapper' => 'booking_email_default_ids_wrapper',
),
);
$form['booking-email-preview'] = array(
'#type' => 'container',
'#children' => "<h3>Email Preview</h3><pre>No email type selected.</pre>",
'#prefix' => '<div id="booking_email_preview_wrapper">',
'#suffix' => '</div>',
);
$form['attachments'] = array(
'#type' => 'fieldset',
'#title' => 'Attach Files',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['attachments']['booking-email-attachment-1'] = array(
'#type' => 'managed_file',
'#title' => t('Email attachment 1'),
'#description' => t('Attach a file to be emailed. Note that this only works with custom email types. File must be 10MB or less, and extension must be one of: ' . variable_get('booking_email_allowed_attachments', 'pdf docx')),
'#upload_location' => 'public://bookings/emails',
'#upload_validators' => array(
'file_validate_size' => array(10*1024*1024),
'file_validate_extensions' => array(variable_get('booking_email_allowed_attachments', 'pdf docx')),
),
);
$form['attachments']['booking-email-attachment-2'] = array(
'#type' => 'managed_file',
'#title' => t('Email attachment 2'),
'#description' => t('Attach a file to be emailed. Note that this only works with custom email types. File must be 10MB or less, and extension must be one of: ' . variable_get('booking_email_allowed_attachments', 'pdf docx')),
'#upload_location' => 'public://bookings/emails',
'#upload_validators' => array(
'file_validate_size' => array(10*1024*1024),
'file_validate_extensions' => array(variable_get('booking_email_allowed_attachments', 'pdf docx')),
),
);
/*
// See https://drupal.stackexchange.com/questions/108583/how-to-save-file-uploaded-with-plupload-integration-module-and-make-it-managed
// For info on saving the attachments from plupload
// Submit handler:
if (!empty($form_state['values']['upload'])) {
$form_state['uploaded_files'] = quotes_file_save_files($form_state['values']['upload']);
}
function quotes_file_save_files($files) {
$saved_files = array();
$scheme = 'private://'; // Change to "public://" if you want to move to public files folder.
foreach ($files as $uploaded_file) {
if ($uploaded_file['status'] == 'done') {
$source = $uploaded_file['tmppath'];
$destination = file_stream_wrapper_uri_normalize($scheme . $uploaded_file['name']);
$destination = file_unmanaged_move($source, $destination, FILE_EXISTS_RENAME);
$file = plupload_file_uri_to_object($destination);
file_save($file);
// Check the $file object to see if all necessary properties are set. Otherwise, use file_load($file->fid) to populate all of them.
// $file = file_load($file->fid);
$saved_files[] = $file;
}
}
return $saved_files;
}
$form['booking-email-attachment'] = array(
'#type' => 'plupload',
'#title' => t('Email attachment'),
'#description' => t('Attach any files to be attached to email. Note that this only works with custom email types.'),
'#upload_validators' => array(
'file_validate_size' => array(10*1024*1024),
'file_validate_extensions' => array(variable_get('booking_email_allowed_attachments', 'pdf docx')),
),
'#plupload_settings' => array(
'runtimes' => 'html5',
'chunk_size' => '1mb',
),
);
*/
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Send Email'),
);
if (variable_get('booking_enable_travelform', 0) == 1) {
$header['travel_form'] = array('data' => t('Travel Submitted?'), 'field' => 'tid');
}
//query the database for studygroup info if it is enabled
if (variable_get('booking_enable_studygroups', 0) == 1) {
//select entries from the study groups mapping table
$query = db_select('booking_studygroup_mapping', 'm');
$query->join('booking_studygroup_list', 's', 's.sid = m.booking_studygroup_id');
$query->condition('m.booking_eventid', $event->eid, '=');
$query->fields('m')->fields('s', array('booking_studygroup_descrip'));
$group_mapping = $query->execute()->fetchAllAssoc('sid');
//add a column to the table header
$header['group_roles'] = array('data' => t('Group Role'));
}
//query for attendee data
$query = db_select('booking_person', 'p');
$query->join('booking_price', 'pr', 'pr.pid = p.booking_payment_id');
$query->leftJoin('booking_travel', 't', 'p.nid = t.booking_person_nid');
$query->fields('p')
->fields('pr', array('booking_price', 'booking_late_price'))
->fields('t')
->condition('p.booking_eventid', $event->eid, '=');
//make the result user-sortable
$table_sort = $query->extend('TableSort')->orderbyHeader($header);
$result = $table_sort->execute();
//generate the tableselect data
foreach($result as $data) {
$group_text = "";
$class = $data->booking_welfare_required == 'Y' ? "welfare-row" : "normal-row";
$options[$data->nid] = array (
'#attributes' => array('class' => array($class)),
'booking_nid' => l(t('!id', array('!id' => $data->nid)), t('node/!id', array('!id' => $data->nid))),
'booking_name' => $data->booking_firstname . " " . $data->booking_lastname,
'booking_gender' => $data->booking_gender == 'M' ? 'Male' : 'Female',
'booking_email' => $data->booking_email,
'booking_state' => $data->booking_state,
'booking_status' => _booking_status_generate($data->booking_status),
'amount_paid' => $data->booking_amount_paid,
'amount_reqd' => $data->booking_total_pay_reqd,
'booking_fully_paid' => $data->booking_payment_complete == 'Y' ? 'Yes' : 'No',
'welfare_required' => $data->booking_welfare_required == 'Y' ? 'Yes' : 'No',
);
//add optional columns if those features are enabled
if (variable_get('booking_enable_travelform', 0) == 1) {
$options[$data->nid]['travel_form'] = $data->tid > 0 ? 'Yes' : 'No';
}
if (variable_get('booking_enable_studygroups', 0) == 1) {
foreach ($group_mapping as $group) {
$role = $group->booking_studygroup_role;
if ($group->booking_node_id == $data->nid && $role > 0) {
$text = _booking_studygroup_role_lookup($role);
$group_text .= "<b>" . $text . "</b> for " . $group->booking_studygroup_descrip . " #" . $group->booking_session_id . "; ";
}
}
$options[$data->nid]['group_roles'] = $group_text;
}
}
$form['table'] = array (
'#type' => 'tableselect',
//'#multiple' => TRUE,
'#header' => $header,
'#options' => $options,
'#default_value' => $values,
'#empty' => t('No attendees found.'),
'#attributes' => array('id' => 'sort-table'),
);
//watchdog('booking_debug', "<pre>Manual email form default values\n@info</pre>", array('@info' => print_r( $values, true)));
//watchdog('booking_debug', "<pre>Manual email form table\n@info</pre>", array('@info' => print_r( $form['table'], true)));
$form['submit-bottom'] = array (
'#type' => 'submit',
'#value' => t('Send Email'),
);
return array (
/*
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
*/
'form' => $form,
);
}
/**
* Callback to update preview of email that will be sent
*
*/
function _booking_email_get_preview_callback($form, $form_state) {
global $event;
$text = "";
$emailtype = $form_state['values']['email-type'];
switch ($emailtype) {
case "registration":
$text = variable_get('booking_email_bookedin_text');
break;
case "balance":
$text = variable_get('booking_email_paymentoutstanding_text');
// perform the checking of HTML value now since we're pre-pending text to it
$text = isset($text['format']) ? $text['value'] : $text;
if (variable_get('booking_enable_combined_pricing', 0) == 1) {
// no <pre> tags necessary if its a HTML mail
if(variable_get('booking_enable_html_mail', 0) == 1) {
$text .= "\n<h3>If married</h3>\n";
}
else {
$text .= "\n</pre><h3>If married</h3>\n<pre>";
}
$married_text = variable_get('booking_email_paymentoutstanding_married_text');
// repeat HTML check for rest of preview
$text .= isset($married_text['format']) ? $married_text['value'] : $married_text;
}
break;
case "complete":
$text = variable_get('booking_email_regn_complete_text');
break;
case "withdrawal":
$text = variable_get('booking_email_notcoming_demotion');
break;
case "missedpayment":
$text = variable_get('booking_email_missedpayment');
break;
case "initialtravelrequired":
$text = variable_get('booking_email_travel_initial_email_text');
break;
case "remindertravelrequired":
$text = variable_get('booking_email_travel_reminder_email_text');
break;
case "travelcomplete":
$text = variable_get('booking_email_travel_complete_text');
break;
case "waitinglistpromotion":
$text = variable_get('booking_email_waitinglistpromotion');
break;
case "waitinglistpromotionfullypaid":
$text = variable_get('booking_email_waitinglistpromotion_fullypaid');
break;
}
//handle custom email types
if (strpos($emailtype, 'custom') !== false) {
$text = variable_get('booking_email_' . $form_state['values']['email-type']);
}
//use the html value if it is set, otherwise use the plaintext input which is just a string
$text = isset($text['format']) ? $text['value'] : $text;
//watchdog('booking_debug', "<pre>Email generation:\n@info</pre>", array('@info' => print_r( $text, true)));
if(variable_get('booking_enable_html_mail', 0) == 1) {
$markup_pre = "<div id=\"booking_email_preview_wrapper\"><h3>Email Preview</h3>";
$markup_post = "<br /><br /></div>";
}
else {
$markup_pre = "<div id=\"booking_email_preview_wrapper\"><h3>Email Preview</h3><pre>";
$markup_post = "</pre><br /><br /></div>";
}
//generate html that will be used to update div booking_email_preview_wrapper
return $markup_pre . $text . $markup_post;
}
/**
* Callback to update hidden form value with default checkbox details
*
* Callback element needs only select the portion of the form to be updated.
* Since #ajax['callback'] return can be HTML or a renderable array (or an
* array of commands), we can just return a piece of the form.
* Source: http://www.maged.me/blog/drupal-7-execute-javascript-code-after-ajax-call
*/
function _booking_email_get_default_selection_callback($form, $form_state) {
global $event;
$defaults = array();
$replacementform_data = array();
//get type of selection from $form_state['values']['booking-email-preselection']
$selection = $form_state['values']['booking-email-preselection'];
//load nodes
$people = booking_load_query(NULL, TRUE);
// Check for the reading group ID
$readinggroup_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid AND booking_is_readinggroup = 'Y'",
array(':eid' => $event->eid));
$readinggroups = $readinggroup_query->fetchObject();
//watchdog('booking_debug', "<pre>Reading Group ID is :\n@info</pre>", array('@info' => print_r($readinggroups, true)));
$readinggroup_regex = '/^session' . $readinggroups->sid . '_role/';
//populate $defaults based on type of selection
foreach ($people as $person) {
switch ($selection) {
case 'notpaid':
if ($person->booking_status == 0) {
$defaults[] = $person->nid;
}
break;
case 'bookedin':
if ($person->booking_status == 1) {
$defaults[] = $person->nid;
}
break;
case 'waitinglist':
if ($person->booking_status == 2) {
$defaults[] = $person->nid;
}
break;
case 'refundreqd':
if ($person->booking_status == 3 && $person->booking_refund_processed == 'N') {
$defaults[] = $person->nid;
}
break;
case 'unpaid':
if ($person->booking_payment_complete == 'N' && $person->booking_status == 1) {
$defaults[] = $person->nid;
}
break;
case 'notravelform':
if ($person->booking_status == 1 && $person->tid == 0) {
$defaults[] = $person->nid;
}
break;
case 'notravelforminclwaiting':
if (($person->booking_status == 1 || $person->booking_status == 2) && $person->tid == 0) {
$defaults[] = $person->nid;
}
break;
case 'leaderhelper':
foreach ($person as $key => $value) {
if (preg_match('/^session(\d+)_role/', $key, $matches) && $value > 0) {
//don't add the person multiple times if they're leading/helping multiple groups
if (! in_array($person->nid, $defaults)) {
$defaults[] = $person->nid;
}
}
}
break;
case 'readinggroup-leader':
foreach ($person as $key => $value) {
if (preg_match($readinggroup_regex, $key, $matches) && $value == 1) {
//don't add the person multiple times if they're leading/helping multiple groups
if (! in_array($person->nid, $defaults)) {
$defaults[] = $person->nid;
}
}
}
break;
} //end switch
} //loop attendees
//create new hidden form element to return
$replacementform_data['booking-email-default-ids'] = array (
'#type' => 'hidden',
'#value' => drupal_json_encode($defaults), //encode the data as json so we can process it with jQuery
'#prefix' => '<div id="booking_email_default_ids_wrapper">',
'#suffix' => '</div>',
'#attributes' => array('id' => 'booking_email_default_ids'),
);
$output_html = render($replacementform_data['booking-email-default-ids']);
$feedback_html = t("<div id=\"booking_email_preselection_suffix_wrapper\">Number of people selected: <b>!num</b></div>",
array('!num' => count($defaults)));
//watchdog('booking_debug', "<pre>Manual Email ajax html\n@info</pre>", array('@info' => print_r( $output_html, true)));
//return a sequence of commands to run
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace("#booking_email_default_ids_wrapper", $output_html),
ajax_command_replace("#booking_email_preselection_suffix_wrapper", $feedback_html),
// This will call the command bookingEmailIDs in our custom JS file.
array('command' => 'bookingAjaxCheckboxes',
'formDataElement' => 'booking_email_default_ids', //name of the hidden form element that contains the json data
'formName' => 'booking-manual-email-form', //note the dashes instead of underscores!
'checkboxName' => 'table', //form element for tableselect
),
)
);
}
/**
* Function to handle sending the manual emails
*/
function booking_manual_email_form_submit($form, &$form_state) {
$counter = 0;
$message = "";
$attachments = array();
$update_messages = array();
$checkboxes = $form_state['values']['table']; //$values['booking_price_active'];
//watchdog('booking', 'Formstate when setting buttons: @info', array ('@info' => var_export($form_state['values'], TRUE)));
//watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE)));
// Add attachments if present
if (isset($form_state['values']['booking-email-attachment-1']) && $form_state['values']['booking-email-attachment-1'] != 0) {
$attachments[] = file_load($form_state['values']['booking-email-attachment-1']);
watchdog('booking_debug', 'File attachment 1 detected: @info', array ('@info' => print_r($attachments, TRUE)));
// NOTE: Since we do nothing to save this file, it should get cleaned up by cron
// As per https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7.x#managed_file
}
if (isset($form_state['values']['booking-email-attachment-2']) && $form_state['values']['booking-email-attachment-2'] != 0) {
$attachments[] = file_load($form_state['values']['booking-email-attachment-2']);
watchdog('booking_debug', 'File attachment 2 detected: @info', array ('@info' => print_r($attachments, TRUE)));
}
foreach($checkboxes as $key => $value) {
//do a sanity check on the key => value pair from the form submission
if (is_numeric($key) && $value != 0) {
//check the person exists in the database
$person = db_query("SELECT person.nid " .
"FROM {booking_person} person " .
"WHERE nid = :nid",
array(':nid' => $key))
->fetchObject();
if ($person) {
if ($form_state['values']['email-type'] == 'registration') {
$message = t('Processing a manual registration email to id @info', array ('@info' => $key));
_booking_registration_email($key, false, true);
}
elseif ($form_state['values']['email-type'] == 'initialtravelrequired') {
$message = t('Processing a manual initial travel form request email to id @info', array ('@info' => $key));
_booking_travelform_initial_request_email($key);
}
elseif ($form_state['values']['email-type'] == 'remindertravelrequired') {
$message = t('Processing a manual reminder travel form request email to id @info', array ('@info' => $key));
_booking_travelform_reminder_request_email($key);
}
elseif ($form_state['values']['email-type'] == 'balance') {
$message = t('Processing a manual outstanding balance email to id @info', array ('@info' => $key));
_booking_balance_payment_email($key);
}
elseif ($form_state['values']['email-type'] == 'complete') {
$message = t('Processing a manual registration complete email to id @info', array ('@info' => $key));
_booking_registration_email($key, true, true);
}
elseif ($form_state['values']['email-type'] == 'travelcomplete') {
$message = t('Processing a manual travelform complete email to id @info', array ('@info' => $key));
_booking_travelform_confirmation_email($key);
}
elseif ($form_state['values']['email-type'] == 'withdrawal') {
$message = t('Processing a manual withdrawal email to id @info', array ('@info' => $key));
_booking_demoted_to_notcoming_email($key);
}
elseif ($form_state['values']['email-type'] == 'missedpayment') {
$message = t('Processing a manual missedpayment email to id @info', array ('@info' => $key));
_booking_missedpayment_email($key);
}
elseif ($form_state['values']['email-type'] == 'waitinglistpromotion') {
$message = t('Processing a manual waitinglistpromotion email to id @info', array ('@info' => $key));
_booking_promoted_from_waitinglist_email($key);
}
elseif ($form_state['values']['email-type'] == 'waitinglistpromotionfullypaid') {
$message = t('Processing a manual waitinglistpromotionfullypaid email to id @info', array ('@info' => $key));
_booking_promoted_from_waitinglist_email($key);
}
elseif (strpos($form_state['values']['email-type'], 'customlogistics') !== false) {
$message = t('Processing a @custom type email from logistics to id @info', array ('@custom' => $form_state['values']['email-type'], '@info' => $key));
_booking_custom_email($key, $form_state['values']['email-type'], 'logistics', $attachment);
}
elseif (strpos($form_state['values']['email-type'], 'custom') !== false) {
$message = t('Processing a @custom type email to id @info', array ('@custom' => $form_state['values']['email-type'], '@info' => $key));
_booking_custom_email($key, $form_state['values']['email-type'], 'contact', $attachments);
}
//increase the counter of people we've emailed
$counter++;
//store info about the email
$update_messages[] = $message;
}
}
}
$final_message = "Sent manual email for $counter people of type " . $form_state['values']['email-type'];
drupal_set_message($final_message, 'status', FALSE);
watchdog('booking', "<pre>" . $final_message . "\n" . implode("\n", $update_messages) . "</pre>");
//watchdog('booking', "Sent manual email for $counter people.");
}

View File

@@ -1,220 +1,46 @@
<?php
function booking_manual_email()
{
/**
* Helper function to put together all the information for theming a HTML based email, if enabled
*
* @param
* @return themed message text
*/
function _booking_generate_html_body($subject, $body, $tokens) {
global $event;
//see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios
$form = array ();
$options = array ();
$group_text = "";
$prefix = t("<p>Send a manual email to people registered for this event.</p>");
$email_options_array = array();
$email_options_array['registration'] = 'Registration Successful Email';
$email_options_array['balance'] = 'Balance Outstanding Email';
$email_options_array['complete'] = 'Payment Complete Email';
$email_options_array['withdrawal'] = 'Withdrawal Processed Email';
$email_options_array['missedpayment'] = 'Missed Payment Email';
$email_options_array['travelrequired'] = 'Travel Form Required Email';
$email_options_array['travelcomplete'] = 'Travel Form Complete Email';
$output_text = "";
//add in the custom email types
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++)
{
$email_options_array['custom' . $i] = variable_get('booking_email_subject_custom' . $i, $event->booking_eventname . ' custom ' . $i);
//Check if we should apply a HTML theme to the email text or just send a normal email
if (variable_get('booking_enable_html_mail', 0) == 1) {
//get the footer text
$message_footer = variable_get('booking_html_mail_footer');
$message_footer = isset($message_footer['format']) ? $message_footer['value'] : $message_footer;
$message_footer = token_replace($message_footer, $tokens);
$colors = json_decode(variable_get('booking_mailtemplate_colors'), TRUE);
$header_links = json_decode(variable_get('booking_mailtemplate_header_links'), TRUE);
$social_links = json_decode(variable_get('booking_mailtemplate_social_links'), TRUE);
$output_text = theme('booking_htmlmail_registration_mail',
array(
'module' => 'booking',
'key' => 'registration_mail',
'body' => $body,
'subject' => $subject,
'footer' => $message_footer,
'colors' => $colors,
'header_links' => $header_links,
'social_links' => $social_links,
));
}
else {
$output_text = $body;
}
$form['email-type'] = array(
'#type' => 'select',
'#title' => t('Email Type'),
'#required' => TRUE,
'#default_value' => '',
'#options' => $email_options_array,
);
$header = array(
'booking_nid' => array('data' => t('Id'), 'field' => 'nid', 'sort' => 'asc'),
'booking_name' => array('data' => t('Name'), 'field' => 'booking_lastname'),
'booking_gender' => array('data' => t('Gender'), 'field' => 'booking_gender'),
'booking_email' => array('data' => t('Email'), 'field' => 'booking_email'),
'booking_state' => array('data' => t('State'), 'field' => 'booking_state'),
'booking_status' => array('data' => t('Status'), 'field' => 'booking_status'),
'amount_paid' => array('data' => t('Payment To Date'), 'field' => 'booking_amount_paid'),
'amount_reqd' => array('data' => t('Total Payment Required'), 'field' => 'booking_total_pay_reqd'),
'booking_fully_paid' => array('data' => t('Fully paid?'), 'field' => 'booking_payment_complete'),
'welfare_required' => array('data' => t('Welfare Required?'), 'field' => 'booking_welfare_required'),
'travel_form' => array('data' => t('Travel Submitted?'), 'field' => 'tid'),
);
if (variable_get('booking_enable_studygroups', 0) == 1)
{
//select entries from the study groups mapping table
$query = db_select('booking_studygroup_mapping', 'm');
$query->join('booking_studygroup_list', 's', 's.sid = m.booking_studygroup_id');
$query->condition('m.booking_eventid', $event->eid, '=');
$query->fields('m')->fields('s', array('booking_studygroup_descrip'));
$group_mapping = $query->execute()->fetchAllAssoc('sid');
//add a column to the table header
$header['group_roles'] = array('data' => t('Group Role'));
//watchdog('booking_debug', "<pre>HTML body themed\n@info</pre>", array('@info' => print_r($output_text, true)));
return $output_text;
}
$query = db_select('booking_person', 'p');
$query->join('booking_price', 'pr', 'pr.pid = p.booking_payment_id');
$query->leftJoin('booking_travel', 't', 'p.nid = t.booking_person_nid');
$query->fields('p')
->fields('pr', array('booking_price', 'booking_late_price'))
->fields('t')
->condition('p.booking_eventid', $event->eid, '=');
$table_sort = $query->extend('TableSort')->orderbyHeader($header);
$result = $table_sort->execute();
foreach($result as $data)
{
$group_text = "";
//$paid = _booking_amount_owing($data);
//$paid = _booking_amount_owing($data->nid);
$options[$data->nid] = array (
'booking_nid' => l(t('!id', array('!id' => $data->nid)), t('node/!id', array('!id' => $data->nid))),
'booking_name' => $data->booking_firstname . " " . $data->booking_lastname,
'booking_gender' => $data->booking_gender == 'M' ? 'Male' : 'Female',
'booking_email' => $data->booking_email,
'booking_state' => $data->booking_state,
'booking_status' => _booking_status_generate($data->booking_status),
'amount_paid' => $data->booking_amount_paid,
'amount_reqd' => $data->booking_total_pay_reqd,
'booking_fully_paid' => $data->booking_payment_complete == 'Y' ? 'Yes' : 'No',
'welfare_required' => $data->booking_welfare_required == 'Y' ? 'Yes' : 'No',
'travel_form' => $data->tid > 0 ? 'Yes' : 'No',
);
if (variable_get('booking_enable_studygroups', 0) == 1)
{
foreach ($group_mapping as $group)
{
$role = $group->booking_studygroup_role;
if ($group->booking_node_id == $data->nid && $role > 0)
{
$text = _booking_studygroup_role_lookup($role);
$group_text .= "<b>" . $text . "</b> for " . $group->booking_studygroup_descrip . " #" . $group->booking_session_id . "; ";
}
}
$options[$data->nid]['group_roles'] = $group_text;
}
//$values[$data->nid] = ($paid == 0 || $data->booking_status != 1) ? FALSE : TRUE;
}
$form['table'] = array (
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
//'#default_value' => $values,
'#empty' => t('No attendees found.'),
'#attributes' => array('id' => 'sort-table'),
);
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Send Email'),
);
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
function booking_manual_email_submit($form, &$form_state) {
$counter = 0;
$update_messages = array();
$checkboxes = $form_state['values']['table']; //$values['booking_price_active'];
//watchdog('booking', 'Formstate when setting buttons: @info', array ('@info' => var_export($form_state['values'], TRUE)));
//watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE)));
foreach($checkboxes as $key => $value)
{
$message = "";
//do a sanity check on the key => value pair from the form submission
if (is_numeric($key) && $value != 0)
{
//check the person exists in the database
$person = db_query("SELECT person.nid " .
"FROM {booking_person} person " .
"WHERE nid = :nid",
array(':nid' => $key))
->fetchObject();
if ($person)
{
if ($form_state['values']['email-type'] == 'registration')
{
$message = t('Processing a manual registration email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual registration email to id @info', array ('@info' => $key));
_booking_registration_email($key, false, true);
}
elseif ($form_state['values']['email-type'] == 'travelrequired')
{
$message = t('Processing a manual travel form request email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual travel form request email to id @info', array ('@info' => $key));
_booking_travelform_request_email($key);
}
elseif ($form_state['values']['email-type'] == 'balance')
{
$message = t('Processing a manual outstanding balance email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual outstanding balance email to id @info', array ('@info' => $key));
_booking_balance_payment_email($key);
}
elseif ($form_state['values']['email-type'] == 'complete')
{
$message = t('Processing a manual registration complete email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual registration complete email to id @info', array ('@info' => $key));
_booking_registration_email($key, true, true);
}
elseif ($form_state['values']['email-type'] == 'travelcomplete')
{
$message = t('Processing a manual travelform complete email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual travelform complete email to id @info', array ('@info' => $key));
_booking_travelform_confirmation_email($key);
}
elseif ($form_state['values']['email-type'] == 'withdrawal')
{
$message = t('Processing a manual withdrawal email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual withdrawal email to id @info', array ('@info' => $key));
_booking_demoted_to_notcoming_email($key);
}
elseif ($form_state['values']['email-type'] == 'missedpayment')
{
$message = t('Processing a manual missedpayment email to id @info', array ('@info' => $key));
//watchdog('booking', 'Processing a manual missedpayment email to id @info', array ('@info' => $key));
_booking_missedpayment_email($key);
}
elseif (strpos($form_state['values']['email-type'], 'custom') !== false)
{
$message = t('Processing a @custom type email to id @info', array ('@custom' => $form_state['values']['email-type'], '@info' => $key));
//watchdog('booking', 'Processing a @custom type email to id @info', array ('@custom' => $form_state['values']['email-type'], '@info' => $key));
_booking_custom_email($key, $form_state['values']['email-type']);
}
//increase the counter of people we've emailed
$counter++;
//store info about the email
$update_messages[] = $message;
}
}
}
$final_message = "Sent manual email for $counter people.";
drupal_set_message($final_message, 'status', FALSE);
watchdog('booking', "<pre>" . $final_message . "\n" . implode("\n", $update_messages) . "</pre>");
//watchdog('booking', "Sent manual email for $counter people.");
}
/**
* Function to send email to registrant after completing registration process
*
@@ -232,8 +58,10 @@ function booking_manual_email_submit($form, &$form_state) {
//load the node matching this id
$node = node_load($nid);
$tokens = booking_define_personspecific_tokens($node);
watchdog('booking', 'Sending registration email to !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
watchdog('booking', 'Sending registration email to !first !last',
array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
//waiting list has already been calculated, stored in node
$waiting_list = $node->booking_status == 2 ? TRUE : FALSE;
@@ -243,33 +71,35 @@ function booking_manual_email_submit($form, &$form_state) {
'!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from')))
));
//send the registering person an email
//calculate fields for email to be sent
$to = $node->booking_email;
$body = _booking_registration_email_generate($node, $waiting_list, $balance_payment, $manual);
if ($balance_payment == TRUE)
if ($balance_payment == TRUE) {
$subject = t('!event Payment Complete', array('!event' => $event->booking_eventname));
else
}
else {
$subject = t('!event Registration', array('!event' => $event->booking_eventname));
}
$params['subject'] = $subject;
$params['body'] = $body;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
$raw_body = _booking_registration_email_generate($node, $tokens, $waiting_list, $balance_payment, $manual);
$themed_body = _booking_generate_html_body($subject, $raw_body, $tokens);
$params['body'] = $themed_body;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//send the email to the person
drupal_mail('booking', 'registration_mail', $to, $language, $params, $from);
//drupal_mail('booking', 'registration_mail', 'it@coadcorp.com', $language, $params, $from);
//send a notification email if we didn't automatically send one earlier
if (variable_get('booking_auto_confirm_email', 0) == 1)
{
if (variable_get('booking_auto_confirm_email', 0) == 1) {
_booking_regn_notifyonly_email($node, $balance_payment);
}
}
/**
@@ -278,14 +108,14 @@ function booking_manual_email_submit($form, &$form_state) {
* @param $node - variable representing the booking node
* @return nothing
*/
function _booking_regn_notifyonly_email($node, $balance_payment)
{
function _booking_regn_notifyonly_email($node, $balance_payment) {
global $event;
global $user;
$language = user_preferred_language($user);
$tokens = booking_define_personspecific_tokens($node);
watchdog('booking', 'Sending notification email about !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
watchdog('booking', 'Sending notification email about !first !last',
array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
//calculate the from email address
$from = t('!event Registrations <!email>', array('!event' => $event->booking_eventname,
@@ -295,19 +125,28 @@ function booking_manual_email_submit($form, &$form_state) {
//just put the registration info in this email to notify the appropriate people
$to = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
if ($balance_payment == TRUE)
$params['subject'] = t('Registration Fully Paid: !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
else
$params['subject'] = t('New Registration: !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
if ($balance_payment == TRUE) {
$subject = t('Registration Fully Paid: !first !last',
array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
}
else {
$subject = t('New Registration: !first !last',
array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
}
$params['subject'] = $subject;
//$params['body'] = _booking_details_email_summary($node);
$params['body'] = token_replace(variable_get('booking_email_notification_text'), $tokens);
$message_body = variable_get('booking_email_notification_text');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
drupal_mail('booking', 'registration_mail_notify', $to, $language, $params, $from);
@@ -321,27 +160,30 @@ function booking_manual_email_submit($form, &$form_state) {
* @param $waiting_list - whether this registration is on on the waiting list
* @return array containing email text
*/
function _booking_registration_email_generate($node, $waiting_list, $balance_payment, $manual) {
function _booking_registration_email_generate($node, $tokens, $waiting_list, $balance_payment, $manual) {
global $event;
$tokens = booking_define_personspecific_tokens($node);
//$tokens = booking_define_personspecific_tokens($node);
$body = "";
if ($balance_payment == True)
{
$contact_message = token_replace(variable_get('booking_email_regn_complete_text'), $tokens);
if ($balance_payment == True) {
$body = variable_get('booking_email_regn_complete_text');
//$contact_message = token_replace(variable_get('booking_email_regn_complete_text'), $tokens);
}
elseif ($waiting_list == False)
{
$contact_message = token_replace(variable_get('booking_email_bookedin_text'), $tokens);
elseif ($waiting_list == False) {
$body = variable_get('booking_email_bookedin_text');
//$contact_message = token_replace(variable_get('booking_email_bookedin_text'), $tokens);
}
else
{
else {
//booking is on the waiting list
$contact_message = token_replace(variable_get('booking_email_waitinglist_text'), $tokens);
$body = variable_get('booking_email_waitinglist_text');
//$contact_message = token_replace(variable_get('booking_email_waitinglist_text'), $tokens);
}
//Use the value of the field if it is an array from a HTML textarea
$body = isset($body['format']) ? $body['value'] : $body;
//watchdog('booking_debug', "<pre>Email generation:\n@info</pre>", array('@info' => print_r( $body, true)));
//$contact_message .= "\n\n" . t("!details", array('!details' => _booking_details_email_summary($node)));
return $contact_message;
return token_replace($body, $tokens);
}
@@ -351,19 +193,21 @@ function booking_manual_email_submit($form, &$form_state) {
*
* @param $nid - the registration node
*/
function _booking_balance_payment_email($nid)
{
function _booking_balance_payment_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
$message_body = "";
//load the node matching this id
$node = node_load($nid);
$tokens = booking_define_personspecific_tokens($node);
if ($tokens['payment-required'] <= 0)
{
watchdog('booking', "Not sending amount owing email, since this person doesn't owe any money: @info", array('@info' => var_export($node, TRUE)));
if ($tokens['payment-required'] <= 0) {
drupal_set_message(t("Ignore below status - didn't send unnecessary balance outstanding email to: !person",
array('!person' => $node->booking_firstname . ' ' . $node->booking_lastname)));
watchdog('booking', "Not sending amount owing email, since this person doesn't owe any money: @info",
array('@info' => var_export($node, TRUE)));
return;
}
@@ -374,30 +218,32 @@ function _booking_balance_payment_email($nid)
//calculate the remaining parameters
$to = $node->booking_email;
//$subject = t('!event Payment Required', array('!event' => $event->booking_eventname));
//$params['subject'] = $subject;
$params['subject'] = token_replace(variable_get('booking_email_paymentoutstanding_subject',
$subject = token_replace(variable_get('booking_email_paymentoutstanding_subject',
t('!event Payment Required', array('!event' => $event->booking_eventname))), $tokens);
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email for a married couple only if we're combining pricing for couples
if (variable_get('booking_enable_combined_pricing', 0) == 1 && $node->booking_partner_id > 0)
{
watchdog('booking', "Sending the married-couple specific outstanding balance email for this person: @info", array('@info' => var_export($node, TRUE)));
$params['body'] = token_replace(variable_get('booking_email_paymentoutstanding_married_text'), $tokens);
if (variable_get('booking_enable_combined_pricing', 0) == 1 && $node->booking_partner_id > 0) {
watchdog('booking', "Sending the married-couple specific outstanding balance email for this person: @info",
array('@info' => var_export($node, TRUE)));
$message_body = variable_get('booking_email_paymentoutstanding_married_text');
}
//otherwise retrieve the body of the email for individuals
else
{
$params['body'] = token_replace(variable_get('booking_email_paymentoutstanding_text'), $tokens);
else {
$message_body = variable_get('booking_email_paymentoutstanding_text');
}
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['subject'] = $subject;
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'registration_mail_bal_outstanding', $to, $language, $params, $from);
}
@@ -407,8 +253,7 @@ function _booking_balance_payment_email($nid)
*
* @param $nid - the registration node
*/
function _booking_partialbalance_payment_email($nid)
{
function _booking_partialbalance_payment_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
@@ -417,8 +262,7 @@ function _booking_partialbalance_payment_email($nid)
$node = node_load($nid);
$tokens = booking_define_personspecific_tokens($node);
if ($tokens['payment-required'] <= 0)
{
if ($tokens['payment-required'] <= 0) {
watchdog('booking', "Not sending amount owing email, since this person doesn't owe any money: @info", array('@info' => var_export($node, TRUE)));
return;
}
@@ -432,19 +276,23 @@ function _booking_partialbalance_payment_email($nid)
$to = $node->booking_email;
$subject = t('!event Partial Payment Received', array('!event' => $event->booking_eventname));
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//TODO: Married couple version of this
$params['body'] = token_replace(variable_get('booking_email_partialpayment_received_text'), $tokens);
$message_body = variable_get('booking_email_partialpayment_received_text');
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'registration_mail_bal_outstanding', $to, $language, $params, $from);
//$params['headers']['Bcc'] = "it@coadcorp.com";
}
@@ -455,56 +303,80 @@ function _booking_partialbalance_payment_email($nid)
* @param $email_type - select which custom email template to use
* @return nothing
*/
function _booking_custom_email($nid, $email_type)
{
function _booking_custom_email($nid, $email_type, $sender = 'contact', $attachments = NULL) {
global $event;
global $user;
$language = user_preferred_language($user);
$params = array();
//calculate the drupal variables to use
$email_subject_variable = 'booking_email_subject_' . $email_type;
$email_body_variable = 'booking_email_' . $email_type;
if ($sender == 'contact') {
//watchdog('booking', 'Sending a custom email from the contact email address.');
//calculate the from email address for a contact email
$from = t('!event Registrations <!email>', array('!event' => $event->booking_eventname,
'!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from')))
));
}
elseif ($sender == 'logistics') {
watchdog('booking_debug', "<pre>Custom logistics email\n@subject\n@body</pre>",
array('@subject' => $email_subject_variable, '@body' => $email_body_variable));
//calculate the from email address for a logistics email
$from = t('!event Registrations <!email>', array('!event' => $event->booking_eventname,
'!email' => variable_get('booking_logistics_email', variable_get('site_mail', ini_get('sendmail_from')))
));
}
//load the node matching this id
$node = node_load($nid);
$tokens = booking_define_personspecific_tokens($node);
//calculate the from email address
$from = t('!event Registrations <!email>', array('!event' => $event->booking_eventname,
'!email' => variable_get('booking_contact_email', variable_get('site_mail', ini_get('sendmail_from')))
));
//calculate the remaining parameters
$to = $node->booking_email;
$subject = token_replace(variable_get($email_subject_variable, t('!event', array('!event' => $event->booking_eventname))), $tokens);
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get($email_body_variable), $tokens);
//get the matching message text and replace any tokens needed
$message_body = variable_get($email_body_variable);
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
// If there was an attachment, then add it
foreach ($attachments as $attachment) {
$file_uri = drupal_realpath($attachment->uri);
// Make sure we can still access the file
if (file_exists($file_uri) && fopen($file_uri, 'r') !== false) {
watchdog('booking_debug', "Adding attachment !name to custom email.", array('!name' => $attachment->filename));
$params['attachment'][] = file_load($attachment->fid);
}
}
//send the email to the person
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
}
/**
* Function to generate email to be sent to the registrant once they move from the waiting list to the coming list
*
* @param $nid - the registration node
*/
function _booking_promoted_from_waitinglist_email($nid)
{
function _booking_promoted_from_waitinglist_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0)
{
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending promoted-from-waitinglist email since that feature is currently disabled.');
return;
}
@@ -522,15 +394,27 @@ function _booking_promoted_from_waitinglist_email($nid)
$to = $node->booking_email;
$subject = t('!event Position Available', array('!event' => $event->booking_eventname));
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get('booking_email_waitinglistpromotion'), $tokens);
if ($tokens['payment-required'] == 0) {
watchdog('booking_debug', 'This person has fully paid so sending promoted-from-waitinglist-fullypaid email.');
$message_body = variable_get('booking_email_waitinglistpromotion_fullypaid');
}
else {
watchdog('booking_debug', 'This person has an outstanding balance of ' . $tokens['payment-required']);
$message_body = variable_get('booking_email_waitinglistpromotion');
}
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
@@ -541,15 +425,13 @@ function _booking_promoted_from_waitinglist_email($nid)
*
* @param $nid - the registration node
*/
function _booking_demoted_to_notcoming_email($nid)
{
function _booking_demoted_to_notcoming_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0)
{
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending not-coming email since that feature is currently disabled.');
return;
}
@@ -568,15 +450,20 @@ function _booking_demoted_to_notcoming_email($nid)
$subject = token_replace(variable_get('booking_email_notcoming_demotion_subject', t('!event', array('!event' => $event->booking_eventname))), $tokens);
//$subject = t('!event withdrawal confirmation', array('!event' => $event->booking_eventname));
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get('booking_email_notcoming_demotion'), $tokens);
$message_body = variable_get('booking_email_notcoming_demotion');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
@@ -587,15 +474,13 @@ function _booking_demoted_to_notcoming_email($nid)
*
* @param $nid - the registration node
*/
function _booking_missedpayment_email($nid)
{
function _booking_missedpayment_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0)
{
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending missed-payment email since that feature is currently disabled.');
return;
}
@@ -614,34 +499,38 @@ function _booking_missedpayment_email($nid)
$subject = token_replace(variable_get('booking_email_missedpayment_subject', t('!event', array('!event' => $event->booking_eventname))), $tokens);
//$subject = t('!event withdrawal confirmation', array('!event' => $event->booking_eventname));
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get('booking_email_missedpayment'), $tokens);
$message_body = variable_get('booking_email_missedpayment');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
}
/**
* Function to generate email to be sent to the attendee requesting them to complete their travel form
* Function to generate email to be sent to the attendee with the _initial_ request to complete their travel form
*
* @param $nid - the registration node
*/
function _booking_travelform_request_email($nid)
{
function _booking_travelform_initial_request_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0)
{
watchdog('booking', 'Not sending travelform confirmation email since that feature is currently disabled.');
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending travelform initial request email since that feature is currently disabled.');
return;
}
@@ -649,8 +538,6 @@ function _booking_travelform_request_email($nid)
$node = node_load($nid, NULL, TRUE);
$tokens = booking_define_personspecific_tokens($node);
watchdog('booking', 'Sending travelform confirmation email to !first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname));
//calculate the from email address
$from = t('!event Travel <!email>', array('!event' => $event->booking_eventname,
'!email' => variable_get('booking_logistics_email', variable_get('site_mail', ini_get('sendmail_from')))
@@ -658,37 +545,91 @@ function _booking_travelform_request_email($nid)
//calculate the remaining parameters
$to = $node->booking_email;
$subject = token_replace(variable_get('booking_email_travel_required_subject', t('!event', array('!event' => $event->booking_eventname))), $tokens);
$subject = token_replace(variable_get('booking_email_travel_initial_email_subject', t('!event', array('!event' => $event->booking_eventname))), $tokens);
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get('booking_email_travel_required_text'), $tokens);
$message_body = variable_get('booking_email_travel_initial_email_text');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
}
/**
* Function to generate email to be sent to the attendee with the _reminder_ request to complete their travel form
*
* @param $nid - the registration node
*/
function _booking_travelform_reminder_request_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending travelform reminder request email since that feature is currently disabled.');
return;
}
//load the node matching this id from the database, ignoring the cache
$node = node_load($nid, NULL, TRUE);
$tokens = booking_define_personspecific_tokens($node);
//calculate the from email address
$from = t('!event Travel <!email>', array('!event' => $event->booking_eventname,
'!email' => variable_get('booking_logistics_email', variable_get('site_mail', ini_get('sendmail_from')))
));
//calculate the remaining parameters
$to = $node->booking_email;
$subject = token_replace(variable_get('booking_email_travel_reminder_email_subject', t('!event', array('!event' => $event->booking_eventname))), $tokens);
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$message_body = variable_get('booking_email_travel_reminder_email_text');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);
}
/**
* Function to generate email to be sent to the attendee once they complete their travel form
*
* @param $nid - the registration node
*/
function _booking_travelform_confirmation_email($nid)
{
function _booking_travelform_confirmation_email($nid) {
global $event;
global $user;
$language = user_preferred_language($user);
//return without doing anything if we shouldn't send workflow emails
if (variable_get('booking_auto_workflow_email', 0) == 0)
{
if (variable_get('booking_auto_workflow_email', 0) == 0) {
watchdog('booking', 'Not sending travelform confirmation email since that feature is currently disabled.');
return;
}
@@ -710,15 +651,20 @@ function _booking_travelform_confirmation_email($nid)
//$subject = t('!event Travel Details Received', array('!event' => $event->booking_eventname));
$params['subject'] = $subject;
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1)
{
$params['headers']['Bcc'] = "it@coadcorp.com, " . variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
} else {
$params['headers']['Bcc'] = "it@coadcorp.com";
if (variable_get('booking_bcc_notify_email_workflow', 0) == 1) {
$params['headers']['Bcc'] = variable_get('booking_notify_email', variable_get('site_mail', ini_get('sendmail_from')));
}
else {
$params['headers']['Bcc'] = BOOKING_EMAIL_DEV_NOTIFY;
}
//retrieve the body of the email
$params['body'] = token_replace(variable_get('booking_email_travel_complete_text'), $tokens);
$message_body = variable_get('booking_email_travel_complete_text');
//Use the value of the field if it is an array from a HTML textarea
$message_body = isset($message_body['format']) ? $message_body['value'] : $message_body;
$message_body = token_replace($message_body, $tokens);
$themed_body = _booking_generate_html_body($subject, $message_body, $tokens);
$params['body'] = $themed_body;
//send the email
drupal_mail('booking', 'booking_email_custom', $to, $language, $params, $from);

539
booking.emails_admin.inc Normal file
View File

@@ -0,0 +1,539 @@
<?php
/**
* Function to allow admin user to define contents of workflow emails that can be sent by Bookings module
*
* @param
* @return form render array
*/
function booking_emails_workflow_admin() {
global $event;
$form = array();
//some initial workflow email definitions
$default_email_text = "Dear [booking:fname],\n" .
"Congratulations, you are officially booked into [booking:eventname]. " .
"Your registration reference number is [booking:booking-id].\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. " .
"We look forward to seeing you (God Willing) at [booking:eventname]!\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_regn_complete_text = "Dear [booking:fname],\n" .
"Thank-you for completing your payment for [booking:eventname].\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. " .
"We look forward to seeing you (God Willing) at [booking:eventname]!\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_waitinglist_text = "Dear [booking:fname],\n" .
"Thank-you for registering to attend [booking:eventname]. Unfortunately the venue for this event is full, and you have been placed on the waiting list to attend.\n" .
"We will contact you if a position becomes available for you. Please don't hesitate to contact us if you have any queries by replying to this email.\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_paymentoutstanding_text = "Dear [booking:fname],\n" .
"Thank-you for registering to attend [booking:eventname]. Our records indicate that you currently have $[booking:payment-required] outstanding to finalise your registration.\n" .
"Please visit [booking:balance-payment-link] in order to make your final payment.\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n";
$booking_email_waitinglistpromotion = "Dear [booking:fname],\n" .
"We have some great news for you. A place at [booking:eventname] for you has just become available. " .
"If you wish to secure your place at [booking:eventname], please visit [booking:balance-payment-link] to make your final payment. " .
"Our records indicate that you currently have $[booking:paypal-total-amount] outstanding (including Paypal transaction fees).\n" .
"Once we have received your payment, you will be sent an automatic confirmation email thanking you for paying your outstanding fees. " .
"If you are paying via Paypal's eCheque feature, please be aware that payments take 3-5 working days to clear, " .
"and you will not receive the confirmation email until that has occurred.\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. We look forward to seeing you, God Willing, at [booking:eventname]\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team.";
$booking_email_waitinglistpromotion_fullypaid = "Dear [booking:fname],\n" .
"We have some great news for you. A place at [booking:eventname] for you has just become available. " .
"Our records indicate that you have already fully paid, so there is nothing further needed to secure your spot.\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. We look forward to seeing you, God Willing, at [booking:eventname]\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team.";
$booking_email_notcoming_demotion = "";
$booking_email_paymentoutstanding_married_text = "";
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form_type = 'text_format';
$form_format = 'full_html';
}
else {
$form_type = 'textarea';
$form_format = NULL;
}
//include the token definitions
$form['tokens'] = array(
'#theme' => 'token_tree',
'#token_types' => array('booking'),
);
/*Text for emails*/
$form['emails'] = array(
'#type' => 'fieldset',
'#title' => 'Built-In Workflow Email Definitions',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
//if HTML mail is enabled, allow user to specify footer
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form['emails']['booking_html_mail_footer'] = array(
'#title' => t('Footer text for HTML email'),
'#description' => t('Enter HTML to go in the footer of the email template (above the social media icons).<br /><strong>NOTE:</strong>&nbsp;No token subsitutions will be made here.'),
'#default_value' => isset(variable_get('booking_html_mail_footer')['value']) ? variable_get('booking_html_mail_footer')['value'] : variable_get('booking_html_mail_footer', '<p>&nbsp;</p>'),
'#type' => 'text_format',
'#format' => 'full_html',
);
}
$form['emails']['booking_email_notification_text'] = array(
'#title' => t('Notification Email'),
'#description' => t('Email to send to the notification email address (defined in general configuration) when a person has registered'),
'#default_value' => isset(variable_get('booking_email_notification_text')['value']) ? variable_get('booking_email_notification_text')['value'] : variable_get('booking_email_notification_text', '[booking:regn-summary]'),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_bookedin_text'] = array(
'#title' => t('Registration Successful Email'),
'#description' => t('Text to use in an email indicating the person has booked in, paid their deposit and is not on the waiting list'),
'#default_value' => isset(variable_get('booking_email_bookedin_text')['value']) ? variable_get('booking_email_bookedin_text')['value'] : variable_get('booking_email_bookedin_text', $default_email_text),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_regn_complete_text'] = array(
'#title' => t('Payment Complete Email'),
'#description' => t('Email text to indicate a person has booked in, fully paid and is not on the waiting list. ' .
'This will be sent either at initial registration if the full amount is paid, or when the balance is paid.'),
'#default_value' => isset(variable_get('booking_email_regn_complete_text')['value']) ? variable_get('booking_email_regn_complete_text')['value'] : variable_get('booking_email_regn_complete_text', $booking_email_regn_complete_text),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_waitinglist_text'] = array(
'#title' => t('Registration on Waiting List Email'),
'#description' => t('Email text to indicate a person has registered but is on the waiting list. ' .
'This will be sent instead of the Registration Successful or Registration Complete emails if the person is on the waiting list.'),
'#default_value' => isset(variable_get('booking_email_waitinglist_text')['value']) ? variable_get('booking_email_waitinglist_text')['value'] : variable_get('booking_email_waitinglist_text', $booking_email_waitinglist_text),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_partialpayment_received_text'] = array(
'#title' => t('Email text to send a person thanking them for their partial payment'),
'#description' => t(''),
'#default_value' => isset(variable_get('booking_email_partialpayment_received_text')['value']) ? variable_get('booking_email_partialpayment_received_text')['value'] : variable_get('booking_email_partialpayment_received_text', ''),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_paymentoutstanding_subject'] = array (
'#type' => 'textfield',
'#title' => t('Balance Outstanding Email Subject'),
'#description' => t('Subject line for email advising attendee they missed the payment deadline'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_paymentoutstanding_subject','[booking:eventname] payment required'),
);
$form['emails']['booking_email_paymentoutstanding_text'] = array(
'#description' => t('Email text to send a person reminding them of how much they owe'),
'#title' => t('Balance Outstanding Email Text'),
'#default_value' => isset(variable_get('booking_email_paymentoutstanding_text')['value']) ? variable_get('booking_email_paymentoutstanding_text')['value'] : variable_get('booking_email_paymentoutstanding_text', $booking_email_paymentoutstanding_text),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_paymentoutstanding_married_text'] = array(
'#title' => t('Email text to send a married couple reminding them of how much they both owe (only applies when combined pricing enabled)'),
'#description' => t(''),
'#default_value' => isset(variable_get('booking_email_paymentoutstanding_married_text')['value']) ? variable_get('booking_email_paymentoutstanding_married_text')['value'] : variable_get('booking_email_paymentoutstanding_married_text', $booking_email_paymentoutstanding_married_text),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_waitinglistpromotion'] = array(
'#title' => t('Email text to send a person on the waiting list when a spot opens up for them but they have an outstanding balance.'),
'#description' => t(''),
'#default_value' => isset(variable_get('booking_email_waitinglistpromotion')['value']) ? variable_get('booking_email_waitinglistpromotion')['value'] : variable_get('booking_email_waitinglistpromotion', $booking_email_waitinglistpromotion),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_waitinglistpromotion_fullypaid'] = array(
'#title' => t('Email text to send a person on the waiting list when a spot opens up for them and they have already fully paid.'),
'#description' => t(''),
'#default_value' => isset(variable_get('booking_email_waitinglistpromotion_fullypaid')['value']) ?
variable_get('booking_email_waitinglistpromotion_fullypaid')['value'] :
variable_get('booking_email_waitinglistpromotion_fullypaid', $booking_email_waitinglistpromotion_fullypaid),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_notcoming_demotion_subject'] = array (
'#type' => 'textfield',
'#title' => t('Withdrawal Processed Email'),
'#description' => t('Subject line for email advising attendee their withdrawal has been processed'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_notcoming_demotion_subject','[booking:eventname] withdrawal processed'),
);
$form['emails']['booking_email_notcoming_demotion'] = array(
'#title' => t('Email text to send a person who withdraws their registration'),
'#description' => t(''),
'#default_value' => isset(variable_get('booking_email_notcoming_demotion')['value']) ? variable_get('booking_email_notcoming_demotion')['value'] : variable_get('booking_email_notcoming_demotion', $booking_email_notcoming_demotion),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_missedpayment_subject'] = array (
'#type' => 'textfield',
'#title' => t('Missed Payment Email Subject'),
'#description' => t('Subject line for email advising attendee they missed the payment deadline'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_missedpayment_subject','[booking:eventname] payment deadline missed'),
);
$form['emails']['booking_email_missedpayment'] = array(
'#title' => t('Missed Payment Email Text'),
'#description' => t('Email text to send a person who missed the payment deadline'),
'#default_value' => isset(variable_get('booking_email_missedpayment')['value']) ? variable_get('booking_email_missedpayment')['value'] : variable_get('booking_email_missedpayment', ''),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_travel_initial_email_subject'] = array (
'#type' => 'textfield',
'#title' => t('Initial Travel Form Required Subject'),
'#description' => t('Subject line for first email requesting attendee to complete the travel form'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_travel_initial_email_subject','[booking:eventname] Travel Details Required'),
);
$form['emails']['booking_email_travel_initial_email_text'] = array(
'#title' => t('Initial Travel Form Required Text'),
'#description' => t('Text for first email requesting attendee to complete the travel form. This email will be sent from the !email email address', array('!email' => variable_get('booking_logistics_email'))),
'#default_value' => isset(variable_get('booking_email_travel_initial_email_text')['value']) ? variable_get('booking_email_travel_initial_email_text')['value'] : variable_get('booking_email_travel_initial_email_text', ''),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_travel_reminder_email_subject'] = array (
'#type' => 'textfield',
'#title' => t('Reminder Travel Form Required Subject'),
'#description' => t('Subject line for reminder email requesting attendee to complete the travel form'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_travel_reminder_email_subject','[booking:eventname] Travel Details Required'),
);
$form['emails']['booking_email_travel_reminder_email_text'] = array(
'#title' => t('Reminder Travel Form Required Text'),
'#description' => t('Text for reminder email requesting attendee to complete the travel form. This email will be sent from the !email email address', array('!email' => variable_get('booking_logistics_email'))),
'#default_value' => isset(variable_get('booking_email_travel_reminder_email_text')['value']) ? variable_get('booking_email_travel_reminder_email_text')['value'] : variable_get('booking_email_travel_reminder_email_text', ''),
'#type' => $form_type,
'#format' => $form_format,
);
$form['emails']['booking_email_travel_complete_subject'] = array (
'#type' => 'textfield',
'#title' => t('Travel Form Complete Subject'),
'#description' => t('Subject line for email indicating a person has completed the travel form'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_travel_complete_subject','[booking:eventname] Travel Details Received'),
);
$form['emails']['booking_email_travel_complete_text'] = array(
'#title' => t('Travel Form Complete Text'),
'#description' => t('Email text to indicate a person has completed the travel form. This email will be sent from the !email email address', array('!email' => variable_get('booking_logistics_email'))),
'#default_value' => isset(variable_get('booking_email_travel_complete_text')['value']) ? variable_get('booking_email_travel_complete_text')['value'] : variable_get('booking_email_travel_complete_text', ''),
'#type' => $form_type,
'#format' => $form_format,
);
//let the builtin hook do all the hard work
return system_settings_form($form, FALSE);
}
/**
* Hook form() to use ajax to allow admin user to define custom emails that can be sent by Bookings module
*
* @param
* @return form render array
*/
function booking_emails_custom_ajax_form($node, &$form_state) {
global $event;
$form = array();
$email_options_array = array();
$data = $node;
$submit_button_disabled = TRUE;
//$email_options_array = _booking_custom_email_types();
$email_options_array['NULL'] = "---";
//add in the custom email types
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++) {
$email_options_array['custom' . $i] = variable_get('booking_email_subject_custom' . $i, $event->booking_eventname . ' custom ' . $i);
}
//add in the custom email types from logistics
for ($i = 1; $i <= 5; $i++) {
$email_options_array['customlogistics' . $i] = variable_get('booking_email_subject_customlogistics' . $i,
$event->booking_eventname . ' logistics custom ' . $i) . " **Logistics**";
}
// Populate some default values if a selection has already been made
//watchdog('booking_debug', 'booking_emails_custom_ajax_form state: <pre>@info</pre>', array('@info' => print_r( $form_state, true)));
if (!isset($form_state['input']['email-type'])) {
$subject_value = "";
$body_value = "";
}
else {
//watchdog('booking_debug', 'booking_emails_custom_ajax_form user has selected email type ' . $form_state['input']['email-type']);
$emailtype = $form_state['input']['email-type'];
$subject_value = $form_state['input']['booking_email_subjectline_custom'];
if(variable_get('booking_enable_html_mail', 0) == 1) {
$body_value = $form_state['input']['booking_email_body_custom']['value'];
}
else {
$body_value = $form_state['input']['booking_email_body_custom'];
}
// only enable the submit button if the email type is not the initial empty one
if ($form_state['input']['email-type'] !== 'NULL') {
$submit_button_disabled = FALSE;
}
}
// Define the textareas in the form differently if HTML emails are enabled
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form_type = 'text_format';
$form_format = 'full_html';
}
else {
$form_type = 'textarea';
$form_format = NULL;
}
$form['#prefix'] = '<div id="booking_emails_custom_fieldset_wrapper">';
$form['#suffix'] = '</div>';
//include the token definitions
$form['tokens'] = array(
'#theme' => 'token_tree',
'#token_types' => array('booking'),
);
$form['email-type'] = array(
'#type' => 'select',
'#title' => t('Email Type'),
'#required' => TRUE,
'#default_value' => 'NULL',
'#options' => $email_options_array,
'#ajax' => array(
'event' => 'change',
'callback' => 'booking_emails_custom_ajax_form_callback',
'wrapper' => 'booking_emails_custom_fieldset_wrapper',
),
);
$form['email-definition'] = array(
'#type' => 'fieldset',
'#title' => 'Email Definition',
//'#prefix' => '<div id="booking_emails_custom_fieldset_wrapper">',
//'#suffix' => '</div>'
);
$form['email-definition']['booking_email_subjectline_custom'] = array (
'#type' => 'textfield',
'#title' => t('Subject line for Custom Email'),
'#size' => 150,
'#maxlength' => 300,
'#value' => $subject_value,
//'#value' => isset($form_state['values']['booking_email_subjectline_custom']) ? $form_state['values']['booking_email_subjectline_custom'] : '',
);
$form['email-definition']['booking_email_body_custom'] = array(
'#title' => t('Email text for custom email'),
'#description' => t(''),
'#value' => $body_value,
//'#value' => isset($form_state['values']['booking_email_body_custom']) ? $form_state['values']['booking_email_body_custom'] : '',
'#type' => $form_type,
'#format' => $form_format,
'#rows' => 20,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#disabled' => $submit_button_disabled,
);
return array (
'form' => $form,
);
}
/**
* Callback function to display the custom email definition for form booking_emails_custom_ajax_form
*/
function booking_emails_custom_ajax_form_callback($form, &$form_state) {
global $event;
$text = "";
$data = $form_state['input'];
//check the selected email type
$emailtype = $form_state['input']['email-type'];
//configure the input text field and textarea based on select field
if (strpos($emailtype, 'custom') !== false) {
$subject = variable_get('booking_email_subject_' . $emailtype, '');
$form['form']['email-definition']['booking_email_subjectline_custom']['#value'] = $subject;
$text = variable_get('booking_email_' . $emailtype, '');
$text = isset($text['format']) ? $text['value'] : $text;
//watchdog('booking_debug', 'custom text: <pre>@info</pre>', array('@info' => print_r( $text, true)));
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form['form']['email-definition']['booking_email_body_custom']['value']['#value'] = $text;
}
else {
$form['form']['email-definition']['booking_email_body_custom']['#value'] = $text;
}
// TODO : Does changing submit button state here do anything?
$form['form']['submit']['#disabled'] = FALSE;
}
else {
$form['form']['email-definition']['booking_email_subjectline_custom']['#value'] = '';
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form['form']['email-definition']['booking_email_body_custom']['value']['#value'] = '';
}
else {
$form['form']['email-definition']['booking_email_body_custom']['#value'] = '';
}
// TODO : Does changing submit button state here do anything?
$form['form']['submit']['#disabled'] = TRUE;
}
//watchdog('booking_debug', 'booking_emails_custom_ajax_form_callback: <pre>@info</pre>', array('@info' => print_r( $form, true)));
// Rebuild the form
$form_state['rebuild'] = TRUE;
return $form['form'];
}
/**
* Process the submission for the custom email definition form
*/
function booking_emails_custom_ajax_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
$emailtype = $values['email-type'];
variable_set('booking_email_subject_' . $emailtype, $values['booking_email_subjectline_custom']);
variable_set('booking_email_' . $emailtype, $values['booking_email_body_custom']);
$form_state['rebuild'] = TRUE;
}
/**
* Function to allow admin user to define custom emails that can be sent by Bookings module
*
* @param
* @return form render array
*/
function booking_emails_custom_admin() {
global $event;
$form = array();
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form_type = 'text_format';
$form_format = 'full_html';
}
else {
$form_type = 'textarea';
$form_format = NULL;
}
//include the token definitions
$form['tokens'] = array(
'#theme' => 'token_tree',
'#token_types' => array('booking'),
);
/*Text for emails*/
$form['custom-emails'] = array(
'#type' => 'fieldset',
'#title' => 'Custom Email Text Definitions',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
//add a bunch of custom emails
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++) {
$subject_fieldname = 'booking_email_subject_custom' . $i;
$body_fieldname = 'booking_email_custom' . $i;
$form['custom-emails'][$subject_fieldname] = array (
'#type' => 'textfield',
'#title' => t('Subject line for Custom Email ' . $i),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get($subject_fieldname,'[booking:eventname]'),
);
$form['custom-emails'][$body_fieldname] = array(
'#title' => t('Email text for custom email ' . $i),
'#description' => t(''),
'#default_value' => isset(variable_get($body_fieldname)['value']) ? variable_get($body_fieldname)['value'] : variable_get($body_fieldname, ''),
'#type' => $form_type,
'#format' => $form_format,
);
}
//let the builtin hook do all the hard work
return system_settings_form($form, FALSE);
}
/**
* Function to allow admin user to define custom logistics emails that can be sent by Bookings module, from the logistics email address
*
* @param
* @return form render array
*/
function booking_emails_customlogistics_admin() {
global $event;
$form = array();
if(variable_get('booking_enable_html_mail', 0) == 1) {
$form_type = 'text_format';
$form_format = 'full_html';
}
else {
$form_type = 'textarea';
$form_format = NULL;
}
//include the token definitions
$form['tokens'] = array(
'#theme' => 'token_tree',
'#token_types' => array('booking'),
);
/*Text for logistics emails*/
$form['custom-logistics-emails'] = array(
'#type' => 'fieldset',
'#title' => 'Custom Logistics Email Text Definitions',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
//add a bunch of custom emails
//@todo add an admin variable for this
for ($i = 1; $i <= 5; $i++) {
$subject_fieldname = 'booking_email_subject_customlogistics' . $i;
$body_fieldname = 'booking_email_customlogistics' . $i;
$form['custom-logistics-emails'][$subject_fieldname] = array (
'#type' => 'textfield',
'#title' => t('Subject line for Logistics Custom Email ' . $i),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get($subject_fieldname,'[booking:eventname] Logistics'),
);
$form['custom-logistics-emails'][$body_fieldname] = array(
'#title' => t('Email text for Logistics Custom Email ' . $i),
'#description' => t(''),
'#default_value' => isset(variable_get($body_fieldname)['value']) ? variable_get($body_fieldname)['value'] : variable_get($body_fieldname, ''),
'#type' => $form_type,
'#format' => $form_format,
);
}
//let the builtin hook do all the hard work
return system_settings_form($form, FALSE);
}

View File

@@ -1,5 +1,4 @@
<?php
// $Id: booking.events.inc,v 0.1 2012/02/28
/**
* @file
@@ -86,6 +85,14 @@ function booking_event_admin_submit($form, &$form_state) {
->condition('eid', $selected_event, '!=')
->execute();
// Disable variety session timeslots not belonging to target event id
db_update('booking_variety_timeslots')
->fields(array (
'booking_variety_status' => 0,
))
->condition('booking_eventid', $selected_event, '!=')
->execute();
//then set our target event id to be active
db_update('booking_event')
->fields(array (
@@ -100,6 +107,8 @@ function booking_event_admin_submit($form, &$form_state) {
menu_cache_clear_all();
menu_rebuild();
// update SQL view
_booking_node_create_mysqlview();
}
@@ -151,7 +160,7 @@ function booking_event_form($node, &$form_state, $create, $editid = 0)
'#default_value' => empty($data->booking_event_start) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_event_start),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
'#date_year_range' => '-1:+5'
);
$form['booking_event_end'] = array(
'#type' => 'date_select',
@@ -159,7 +168,7 @@ function booking_event_form($node, &$form_state, $create, $editid = 0)
'#default_value' => empty($data->booking_event_end) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_event_end),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
'#date_year_range' => '-1:+5'
);
$form['booking_register_open'] = array(
'#type' => 'date_select',
@@ -167,7 +176,7 @@ function booking_event_form($node, &$form_state, $create, $editid = 0)
'#default_value' => empty($data->booking_register_open) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_register_open),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
'#date_year_range' => '-1:+5'
);
$form['booking_earlybird_close'] = array(
'#type' => 'date_select',
@@ -175,7 +184,7 @@ function booking_event_form($node, &$form_state, $create, $editid = 0)
'#default_value' => empty($data->booking_earlybird_close) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_earlybird_close),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
'#date_year_range' => '-1:+5'
);
$form['booking_register_close'] = array(
'#type' => 'date_select',
@@ -183,7 +192,7 @@ function booking_event_form($node, &$form_state, $create, $editid = 0)
'#default_value' => empty($data->booking_register_close) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_register_close),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
'#date_year_range' => '-1:+5'
);
@@ -295,5 +304,8 @@ function booking_event_form_submit($form, &$form_state) {
->execute();
}
// update SQL view
_booking_node_create_mysqlview();
$form_state['redirect'] = array('admin/config/booking/events');
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,44 @@
<?php
// $Id: booking.import_data.inc,v 0.1
/**
* @file
* Provide functionality to upload csv for bulk update of payment data
*/
function booking_import_data_admin()
function booking_import_data_admin($form, &$form_state)
{
global $event;
$prefix = t("<p>Upload csv file containing data to import. Minimum fields present should be <strong>nid</strong>, " .
" along with user-specified fields of <strong>!config</strong>. CSV Column names should match exactly (case sensitive).</p>",
array('!config' => variable_get('booking_import_include_fields', '')));
$prefix .= "<p>Note that only registration specific data like phone numbers, barcodes, etc can be updated, as well as study group membership and roles. Other data like room allocations cannot be uploaded at this time.</p>";
$form = array();
$prefix = t("<p>Upload csv file containing data to import. Minimum fields present should be <strong>nid</strong> or <strong>booking_tempid</strong>, " .
" along with fields specified below. CSV Column names should match exactly (case sensitive).</p>");
$prefix .= "<p>Note that only registration specific data like phone numbers, barcodes, etc can be updated. Other data like room allocations cannot be uploaded at this time.</p>";
$prefix .= "<p>Also note that updating study group membership and roles requires nid to be present in the input file.</p>";
$form['file'] = array(
'#type' => 'file',
'#title' => t('CSV data'),
'#description' => t('Upload CSV data to be processed'),
);
// Get the database fields and sort them alphabetically to make it easier to find
$booking_view_fields = _booking_get_person_fields();
sort($booking_view_fields, SORT_NATURAL | SORT_FLAG_CASE);
//$nid_index = array_search("nid", $booking_view_fields);
$select_array = array_combine($booking_view_fields, $booking_view_fields);
$form['booking_import_data_fields'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Select database fields for this import'),
'#description' => t('Select database fields to import from an uploaded CSV file. Ensure you hold down control/command when selecting multiple options. ' .
'Fields are sorted alphabetically.'),
'#options' => $select_array,
'#size' => 10,
'#default_value' => isset($form_state['input']['booking_import_data_fields']) ? $form_state['input']['booking_import_data_fields'] : 'nid',
//'#default_value' => variable_get('booking_import_include_fields_dynamic', ''),
);
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Submit'),
@@ -61,7 +76,7 @@ function booking_import_data_admin_validate($form, &$form_state) {
function booking_import_data_admin_submit($form, &$form_state)
{
global $event;
$array = array();
$csvdata = array();
//$expected_fields = array('nid', 'booking_amount_paid', 'booking_total_pay_reqd', 'booking_status');
$error = false;
$update_counter = 0;
@@ -71,8 +86,16 @@ function booking_import_data_admin_submit($form, &$form_state)
$datetime_fields = array('booking_outflight_origin_ts', 'booking_outflight_destination_ts', 'booking_rtrnflight_origin_ts',
'booking_rtrnflight_destination_ts','booking_dob', 'booking_passport_expiry_date');
$builtin_fields_to_import = array('nid');
$custom_fields_to_import = explode(";", variable_get('booking_import_include_fields', ''));
$fields_to_import = array_merge($builtin_fields_to_import, $custom_fields_to_import);
// These are fields we can use to key the update
$unique_fields = array('nid', 'booking_tempid');
$update_key = "";
//$custom_fields_to_import = explode(";", variable_get('booking_import_include_fields', ''));
$data = $form_state['input'];
$import_fields = $data['booking_import_data_fields'];
$fields_to_import = array_merge($builtin_fields_to_import, $import_fields);
watchdog('booking_debug', "<pre>CSV import fields\n@info</pre>", array('@info' => print_r($fields_to_import, true)));
//get the file name from temporary storage field
$file = $form_state['storage']['file'];
@@ -94,7 +117,7 @@ function booking_import_data_admin_submit($form, &$form_state)
$headerRecord = $rowData;
} else {
foreach( $rowData as $key => $value) {
$array[$rowCounter - 1][ $headerRecord[$key] ] = $value;
$csvdata[$rowCounter - 1][ $headerRecord[$key] ] = $value;
}
}
$rowCounter++;
@@ -107,11 +130,10 @@ function booking_import_data_admin_submit($form, &$form_state)
return;
}
//watchdog('booking', "<pre>Import data:\n@info</pre>", array('@info' => print_r( $array, true)));
//watchdog('booking', "<pre>Import data:\n@info</pre>", array('@info' => print_r( $csvdata, true)));
//process the input data
foreach ($array as $record)
{
foreach ($csvdata as $record) {
$rows = 0;
//watchdog('booking', "<pre>Processing row data:\n@info</pre>", array('@info' => print_r( $record, true)));
$update_counter++;
@@ -120,119 +142,78 @@ function booking_import_data_admin_submit($form, &$form_state)
$studygroups_update_array = array();
$studygroup_roles_update_array = array();
//do some error checking
foreach($fields_to_import as $field)
{
/*
if (! isset($record[$field]))
watchdog('booking', 'Non-set field !field: !info', array ('!field' => $field, '!info' => var_export($record, TRUE)));
if ($record[$field] == '')
watchdog('booking', 'Blank field !field: !info', array ('!field' => $field, '!info' => var_export($record, TRUE)));
*/
// Check that there is a key we can use to perform the update
foreach ($unique_fields as $key) {
if (array_key_exists($key, $record)) {
$update_key = $key;
}
}
// Check that we found a key, otherwise the update can't be processed
if ($key === "") {
drupal_set_message("Error: Unable to locate any unique identifier in input file for record number $update_counter.", 'error', FALSE);
break;
}
// Pre-process some data
foreach($fields_to_import as $field) {
//make sure to skip the nid field since we can't update that
if ($field == 'nid')
{
//do nothing
if (in_array($field, $unique_fields)) {
//Don't add this identifier to the list of updates
}
//convert the booking status to the number used internally
elseif ($field == 'booking_status')
{
elseif ($field == 'booking_status') {
$update_text .= " set booking status to '" . $record[$field] . "'; ";
$update_array[$field] = _booking_status_lookup($record[$field]);
}
//check for fields that need to be converted to a timestamp from text
elseif (in_array($field, $datetime_fields))
{
elseif (in_array($field, $datetime_fields)) {
$update_array[$field] = _datetime_to_ts_nonstrict($record[$field]);
$update_text .= " set '" . $field . "' to '" . $update_array[$field] . "'; ";
}
elseif ( (! isset($record[$field])) || $record[$field] == '' )
{
elseif ( (! isset($record[$field])) || $record[$field] == '') {
//drupal_set_message("Error: Unable to locate expected field '$field' in input file for record number $update_counter.", 'error', FALSE);
//watchdog('booking', 'Processing user record: @info', array ('@info' => $record['nid']));
//$error = true;
//skip to the next record
//continue 2;
}
elseif (preg_match('/session(\d{1,2})_role/i', $field, $matches))
{
elseif (preg_match('/session(\d{1,2})_role/i', $field, $matches)) {
$session_id = $matches[1];
//drupal_set_message(t('Setting session id !field role to value: !info', array ('!field' => $session_id, '!info' => var_export($record[$field], TRUE))));
$studygroup_roles_update_array[$session_id] = $record[$field];
}
elseif (preg_match('/session(\d{1,2})$/i', $field, $matches))
{
elseif (preg_match('/session(\d{1,2})$/i', $field, $matches)) {
$session_id = $matches[1];
//drupal_set_message(t('Setting session id !field group to value: !info', array ('!field' => $session_id, '!info' => var_export($record[$field], TRUE))));
$studygroups_update_array[$session_id] = $record[$field];
}
else
{
else {
$update_text .= " set '" . $field . "' to '" . $record[$field] . "'; ";
$update_array[$field] = $record[$field];
}
}
if (count($update_array) > 0)
{
// Perform the actual update
if (count($update_array) > 0) {
$query = db_update('booking_person')
->fields($update_array)
->condition('nid', $record['nid']);
->condition($key, $record[$key]);
$rows = $query->execute();
$update_messages[] = t("Update Query:<br />@info<br />Condition: @nid<br />Rows affected: @rows<br />Values: <br /><pre>@values</pre>", array('@info' => (string) $query, '@nid' => $record['nid'], '@rows' => $rows, '@values' => print_r( $update_array, true) ));
$update_messages[] = t("Update Query:<br />@info<br />Condition: @nid<br />Rows affected: @rows<br />Values: <br /><pre>@values</pre>",
array('@info' => (string) $query, '@nid' => $record[$key], '@rows' => $rows, '@values' => print_r( $update_array, true) ));
}
//handle study group processing
//handle study group processing only if the node id was used as a key
if (isset($record['nid'])) {
$update_text .= _booking_import_studygroup_info($record['nid'], $studygroups_update_array, $studygroup_roles_update_array);
drupal_set_message(t("Updating record !nid as follows: !update", array('!nid' => $record['nid'], '!update' => $update_text)));
//$args = $query->getArguments();
/*
watchdog('booking', "Update Query:<br />@info<br />Condition: @nid<br />Rows affected: @rows<br />Values: <br /><pre>@values</pre>",
array('@info' => (string) $query, '@nid' => $record['nid'], '@rows' => $rows, '@values' => print_r( $update_array, true) ));
*/
/*
$result_array[] = t('Setting payment for id !nid to $!price of total required $!total and status to !status',
array('!nid' => $record['nid'],
'!price' => $record['booking_amount_paid'],
'!total' => $record['booking_total_pay_reqd'],
'!status' => _booking_status_lookup($record['booking_status'])
)
);
*/
/*
//TODO: output this from $result_array
drupal_set_message(t('Setting payment for id !nid to $!price of total required $!total and status to !status',
array('!nid' => $record['nid'],
'!price' => $record['booking_amount_paid'],
'!total' => $record['booking_total_pay_reqd'],
'!status' => _booking_status_lookup($record['booking_status']))
));
*/
// watchdog('booking', 'Setting payment for regn id !nid to $!price and status to !status',
// array('!nid' => $record['nid'], '!price' => $record['booking_amount_paid'], '!status' => _booking_status_lookup($record['booking_status'])));
/*
db_update('booking_person')
->fields(array(
'booking_amount_paid' => $record['booking_amount_paid'],
'booking_total_pay_reqd' => $record['booking_total_pay_reqd'],
'booking_status' => _booking_status_lookup($record['booking_status']),
))
->condition('nid', $record['nid'])
->execute();
*/
}
drupal_set_message(t("Updating record !nid as follows: !update", array('!nid' => $record[$key], '!update' => $update_text)));
} //end processing input data
//output our results to watchdog
//watchdog('booking', '<pre>@print_r</pre>', array('@print_r', print_r( $result_array, TRUE)));
watchdog('booking', "<pre>Processing row data:\n@info</pre>", array('@info' => print_r($update_array, true)));
//delete the uploaded file
file_delete($file);

View File

@@ -1,9 +1,10 @@
; $Id$
name = Booking System
description = "A module which provides a booking system for event registration."
package = Booking System
dependencies[] = date
dependencies[] = token
version = 0.2
configure = admin/config/booking
dependencies[] = libraries
dependencies[] = mimemail
version = 0.3
configure = admin/config/booking/general
core = 7.x

View File

@@ -93,7 +93,7 @@ function booking_update_7201() {
* Add table for variety sessions
*/
function booking_update_7202() {
$booking_variety_options = array(
$booking_variety_sessions = array(
'fields' => array(
'vid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -105,7 +105,7 @@ function booking_update_7202() {
),
'primary key' => array('vid'),
);
$booking_variety_times = array(
$booking_variety_timeslots = array(
'fields' => array(
'tid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -127,8 +127,8 @@ function booking_update_7202() {
);
db_create_table('booking_variety_options', $booking_variety_options);
db_create_table('booking_variety_times', $booking_variety_times);
db_create_table('booking_variety_sessions', $booking_variety_sessions);
db_create_table('booking_variety_timeslots', $booking_variety_timeslots);
db_create_table('booking_variety_regn', $booking_variety_regn);
//TODO: create tables for variety session timeslots and variety session registrations (map user to variety session id)
@@ -531,6 +531,307 @@ function booking_update_7232() {
db_change_field('booking_person', 'booking_event_id', 'booking_eventid', $spec);
}
/**
* Ensure SQL View booking_person_view is created
*/
function booking_update_7233() {
_booking_node_create_mysqlview();
}
/**
* Remove deprecated passport and flight details
*/
function booking_update_7234() {
$fields = array(
'booking_passport_expiry_date', 'booking_passport_num', 'booking_passport_issue_location',
'booking_passport_issue_name', 'booking_destination_country', 'booking_travel_insurance',
'booking_outflight_bookingnum', 'booking_outflight_flightnum', 'booking_outflight_origin',
'booking_outflight_origin_ts', 'booking_outflight_connecting_flightnum', 'booking_outflight_destination',
'booking_outflight_destination_ts', 'booking_rtrnflight_bookingnum', 'booking_rtrnflight_flightnum',
'booking_rtrnflight_origin', 'booking_rtrnflight_origin_ts', 'booking_rtrnflight_connecting_flightnum',
'booking_rtrnflight_destination', 'booking_rtrnflight_destination_ts'
);
foreach ($fields as $field) {
db_drop_field('booking_person', $field);
}
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add email address for guardian contact info
*/
function booking_update_7235() {
$spec = array('type' => 'varchar', 'length' => '250', 'not null' => FALSE);
db_add_field('booking_person', 'booking_guardian_email', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add flag to indicate a studygroup session has been manually assigned
*/
function booking_update_7236() {
$spec = array('type' => 'varchar', 'length' => '1', 'not null' => FALSE, 'default' => 'N');
db_add_field('booking_studygroup_mapping', 'booking_session_manually_allocated', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add flag to indicate an attendee that should be kept separate for automated group calculations
*/
function booking_update_7237() {
$spec = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0);
db_add_field('booking_person', 'booking_keepseparate_id', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add description field to room definitions
*/
function booking_update_7238() {
$spec = array('type' => 'varchar', 'length' => '200', 'not null' => FALSE);
db_add_field('booking_room_definition', 'booking_room_description', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Change room number field in room definitions to integer
*/
function booking_update_7239() {
$spec = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0);
db_change_field('booking_room_definition', 'booking_room_number', 'booking_room_number', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add stripe token field to booking_payments table
*/
function booking_update_7240() {
$spec = array('type' => 'varchar', 'length' => '200', 'not null' => FALSE);
db_add_field('booking_payment', 'booking_stripe_token', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Change stripe token field to store stripe charge response as JSON
*/
function booking_update_7241() {
$spec = array('type' => 'text', 'not null' => FALSE);
db_change_field('booking_payment', 'booking_stripe_token', 'booking_stripe_response', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add support for early registration code
*/
function booking_update_7242() {
//add field to booking_person table
$spec = array('type' => 'int', 'length' => '11', 'not null' => FALSE);
db_add_field('booking_person', 'booking_earlyaccess_code_id', $spec);
//create new table to store the valid codes
$booking_earlyaccess_codes = array(
'fields' => array(
'cid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_earlyaccess_code' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_earlyaccess_code_avail' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_earlyaccess_code_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10'),
),
'primary key' => array('cid'),
);
db_create_table('booking_earlyaccess_codes', $booking_earlyaccess_codes);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add support for html emails
*/
function booking_update_7243() {
$current = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
$addition = array('booking' => 'BookingMailSystem');
variable_set('mail_system', array_merge($current, $addition));
}
/**
* Rename booking_regn_earlyaccess_codes table to booking_earlyaccess_codes
*/
function booking_update_7244() {
db_drop_table('booking_regn_earlyaccess_codes');
//create new table to store the valid codes
$booking_earlyaccess_codes = array(
'fields' => array(
'cid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_earlyaccess_code' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_earlyaccess_code_avail' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_earlyaccess_code_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10'),
),
'primary key' => array('cid'),
);
//db_create_table('booking_earlyaccess_codes', $booking_earlyaccess_codes);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Rename booking_earlyaccess_code back to booking_earlyaccess_code_id in booking_person table
*/
/*
function booking_update_7245() {
$spec = array('type' => 'int', 'length' => '11', 'not null' => FALSE);
db_change_field('booking_person', 'booking_earlyaccess_code', 'booking_earlyaccess_code_id', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
*/
/**
* Add node id to booking_earlyaccess_codes table
*/
/*
function booking_update_7246() {
$spec = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10');
db_add_field('booking_earlyaccess_codes', 'booking_earlyaccess_code_nid', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
*/
/**
* Add field for attendee's music choice
*/
function booking_update_7247() {
$spec = array('type' => 'varchar', 'length' => '500', 'not null' => FALSE);
db_add_field('booking_person', 'booking_song_choice', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Increase maximum length of booking_medical_conditions field to 5000 characters
*/
function booking_update_7248() {
$spec = array('type' => 'varchar', 'length' => '5000', 'not null' => FALSE);
db_change_field('booking_person', 'booking_medical_conditions', 'booking_medical_conditions', $spec);
}
/**
* Add field for attendee's freestyle text entry
*/
function booking_update_7249() {
$spec = array('type' => 'varchar', 'length' => '1000', 'not null' => FALSE);
db_add_field('booking_person', 'booking_freestyle_text', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Deprecated - Create table to store configuration for HTML email templates
*/
/*
function booking_update_7250() {
$booking_mailtemplate_fields = array(
'fields' => array(
'mid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_mailtemplate_media_type' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_mailtemplate_link_title' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_mailtemplate_icon_url' => array('type' => 'varchar', 'length' => '1000', 'not null' => FALSE),
'booking_mailtemplate_link_url' => array('type' => 'varchar', 'length' => '1000', 'not null' => FALSE),
'booking_mailtemplate_link_active' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
),
'primary key' => array('mid'),
);
db_create_table('booking_mailtemplate_fields', $booking_mailtemplate_fields);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
*/
/**
* Add custom cache table
*/
function booking_update_7252() {
if (!db_table_exists('cache_booking')) {
$schema = drupal_get_schema_unprocessed('system', 'cache');
$schema['description'] = 'Cache table used by booking module.';
db_create_table('cache_booking', $schema);
}
}
/**
* Add field to store waiting list position
*/
function booking_update_7253() {
$spec = array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE);
db_add_field('booking_person', 'booking_waitlist_pos', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Change booking_variety_regn field type and rename some tables
*/
function booking_update_7254() {
$spec = array('type' => 'varchar', 'length' => '1000', 'not null' => FALSE);
db_change_field('booking_variety_regn', 'booking_variety_id', 'booking_variety_ids', $spec);
db_rename_table('booking_variety_times', 'booking_variety_timeslots');
db_rename_table('booking_variety_options', 'booking_variety_sessions');
}
/**
* Fix incorrect field name in booking_variety_regn table
*/
function booking_update_7255() {
$spec = array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10');
db_change_field('booking_variety_regn', 'booking_node_id', 'booking_person_nid', $spec);
_booking_node_create_mysqlview();
}
/**
* Add fields for study group definitions
*/
function booking_update_7256() {
$spec = array('type' => 'varchar', 'length' => '500', 'not null' => FALSE);
db_add_field('booking_studygroup_list', 'booking_studygroup_weekday', $spec);
db_add_field('booking_studygroup_list', 'booking_studygroup_explanation', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add field to store URL to QR code
*/
function booking_update_7257() {
$spec = array('type' => 'varchar', 'length' => '500', 'not null' => FALSE);
db_add_field('booking_person', 'booking_qrcode_url', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Add field to store number of previous study weeks
*/
function booking_update_7258() {
$spec = array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE);
db_add_field('booking_person', 'booking_prev_sw_count', $spec);
//update the view to match the new table definition
_booking_node_create_mysqlview();
}
/**
* Implementation of hook_install().
*/
@@ -547,7 +848,7 @@ $result = db_insert('booking_price')
'booking_depositonly' => 1,
))
->execute();
//earlybird close is 31st Jan 2012 at 13:59:59 UTC
$result = db_insert('booking_event')
->fields(array(
'booking_eventname' => 'Sample Event',
@@ -558,7 +859,8 @@ $result = db_insert('booking_event')
))
->execute();
//earlybird close is 31st Jan 2012 at 13:59:59 UTC
//create the sql view booking_person_view when first installing this module
_booking_node_create_mysqlview();
}
/**
@@ -569,26 +871,56 @@ function booking_uninstall() {
//drupal_uninstall_schema('booking');
}
/**
* Implement hook_enable()
* Based on https://drupal.stackexchange.com/questions/23821/email-a-whole-node-including-template-contents
*/
function booking_enable() {
drupal_set_message($message = t('The Booking System module was successfully enabled.'), $type = 'status');
$current = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
//$addition = array('booking' => 'BookingMailSystem');
// Use MimeMail module instead of our own version
$addition = array('booking' => 'MimeMailSystem');
variable_set('mail_system', array_merge($current, $addition));
}
/**
* Implement hook_disable()
*/
function booking_disable() {
drupal_set_message($message = t('The Booking System module was successfully disabled.'), $type = 'status');
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
unset($mail_system['booking']);
variable_set('mail_system', $mail_system);
}
/**
* Implementation of hook_schema().
*/
function booking_schema() {
//configure our own cache table
$schema['cache_booking'] = drupal_get_schema_unprocessed('system', 'cache');
$schema['booking_person'] = array(
'fields' => array(
//identifiers
'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE),
'booking_tempid' => array('type' => 'varchar', 'length' => '40', 'not null' => FALSE),
'booking_earlyaccess_code_id' => array('type' => 'int', 'length' => '11', 'not null' => FALSE),
'booking_timestamp' => array('type' => 'int', 'not null' => TRUE, 'disp-width' => '11'),
'booking_firstname' => array('type' => 'varchar', 'length' => '50', 'not null' => TRUE),
'booking_lastname' => array('type' => 'varchar', 'length' => '50', 'not null' => TRUE),
'booking_gender' => array('type' => 'varchar', 'length' => '1', 'not null' => TRUE),
'booking_dob' => array('type' => 'int', 'not null' => TRUE, 'disp-width' => '11'),
'booking_status' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE),
'booking_waitlist_pos' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE),
'booking_committee_member' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE, 'default' => 'N'),
'booking_welfare_required' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE, 'default' => 'N'),
'booking_barcode' => array('type' => 'varchar', 'length' => '20', 'not null' => FALSE),
'booking_qrcode_url' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_luckynum' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_readinggroup' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_shirt_size' => array('type' => 'varchar', 'length' => '20', 'not null' => FALSE),
@@ -615,6 +947,7 @@ function booking_schema() {
'booking_dependant_children' => array('type' => 'varchar', 'length' => '1', 'not null' => TRUE, 'default' => 'N'),
'booking_bf_gf' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE),
'booking_bf_gf_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10'),
'booking_keepseparate_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_mate1' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_room_mate2' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
//payment info
@@ -629,6 +962,7 @@ function booking_schema() {
//emergency contact info
'booking_guardian_name' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE),
'booking_guardian_type' => array('type' => 'varchar', 'length' => '100', 'not null' => TRUE),
'booking_guardian_email' => array('type' => 'varchar', 'length' => '250', 'not null' => FALSE),
'booking_guardian_phone' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE),
'booking_guardian_phone_alt' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE),
'booking_medicare' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE),
@@ -661,6 +995,9 @@ function booking_schema() {
'booking_firstaid' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_nurse' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_doctor' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_song_choice' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_freestyle_text' => array('type' => 'varchar', 'length' => '1000', 'not null' => FALSE),
'booking_prev_sw_count' => array('type' => 'int', 'length' => '11', 'default' => 0, 'not null' => FALSE),
/*
),
'foreign keys' => array(
@@ -676,6 +1013,7 @@ function booking_schema() {
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
*/
/*
//passport info
'booking_passport_expiry_date' => array('type' => 'int', 'not null' => FALSE, 'disp-width' => '11'),
'booking_passport_num' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE),
@@ -699,6 +1037,7 @@ function booking_schema() {
'booking_rtrnflight_connecting_flightnum' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_rtrnflight_destination' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_rtrnflight_destination_ts' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
*/
/*
),
'foreign keys' => array(
@@ -714,8 +1053,6 @@ function booking_schema() {
'primary key' => array('nid'),
);
$schema['booking_event'] = array(
'fields' => array(
'eid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -762,11 +1099,13 @@ function booking_schema() {
'booking_buyer_email' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_payer_status' => array('type' => 'varchar', 'length' => '50', 'not null' => FALSE),
'booking_item_name' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_ipn_track_id' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE)),
'booking_ipn_track_id' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
'booking_stripe_token' => array('type' => 'varchar', 'length' => '200', 'not null' => FALSE),
),
'primary key' => array('payid'),
);
$schema['booking_variety_options'] = array(
$schema['booking_variety_sessions'] = array(
'fields' => array(
'vid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -779,7 +1118,7 @@ function booking_schema() {
'primary key' => array('vid'),
);
$schema['booking_variety_times'] = array(
$schema['booking_variety_timeslots'] = array(
'fields' => array(
'tid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -794,8 +1133,8 @@ function booking_schema() {
$schema['booking_variety_regn'] = array(
'fields' => array(
'rid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_variety_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_node_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_variety_ids' => array('type' => 'varchar', 'length' => '1000', 'not null' => TRUE),
'booking_person_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
),
'primary key' => array('rid'),
);
@@ -825,6 +1164,8 @@ function booking_schema() {
'sid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_studygroup_descrip' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_studygroup_weekday' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_studygroup_explanation' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_num_group_sessions' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10', 'default' => 1),
'booking_is_readinggroup' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
),
@@ -839,13 +1180,13 @@ function booking_schema() {
'booking_node_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_studygroup_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_session_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10', 'default' => 0),
//'booking_is_leader' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
//'booking_is_helper' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_session_manually_allocated' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE, 'default' => 'N'),
'booking_studygroup_role' => array('type' => 'varchar', 'length' => '100', 'not null' => FALSE, 'default' => 0),
),
'primary key' => array('sid'),
);
//this table isn't currently in use
$schema['booking_readinggroup_definition'] = array(
'fields' => array(
'rid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
@@ -859,11 +1200,12 @@ function booking_schema() {
'fields' => array(
'rid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_room_location_id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_number' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_room_number' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_singlebeds' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_doublebeds' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_queenbeds' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10', 'default' => 0),
'booking_room_ensuite' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE, 'default' => 'N'),
'booking_room_description' => array('type' => 'varchar', 'length' => '200', 'not null' => TRUE),
),
'primary key' => array('rid'),
);
@@ -888,5 +1230,17 @@ function booking_schema() {
'primary key' => array('mid'),
);
//This lists all the early registration access codes
$schema['booking_earlyaccess_codes'] = array(
'fields' => array(
'cid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_eventid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'disp-width' => '10'),
'booking_earlyaccess_code' => array('type' => 'varchar', 'length' => '500', 'not null' => FALSE),
'booking_earlyaccess_code_avail' => array('type' => 'varchar', 'length' => '1', 'not null' => FALSE),
'booking_earlyaccess_code_nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'disp-width' => '10'),
),
'primary key' => array('cid'),
);
return $schema;
}

18
booking.js Normal file
View File

@@ -0,0 +1,18 @@
/**
* Drupal AJAX framework command.
*/
Drupal.ajax.prototype.commands.bookingAjaxCheckboxes = function(ajax, response, status) {
jQuery(function($) {
var arr = $.parseJSON($('input#' + response.formDataElement).val())
$('#' + response.formName).find(':checkbox[name^="' + response.checkboxName + '"]').each(function () {
//.prop() doesn't exist in Drupal's old version of jQuery so use .attr() instead
if ($.inArray($(this).val(), arr) != -1) {
$(this).attr("checked", true);
$(this).closest('tr').addClass("selected");
} else {
$(this).attr("checked", false);
$(this).closest('tr').removeClass("selected");
}
});
});
}

View File

@@ -0,0 +1,241 @@
<?php
/**
* Function to allow admin user to define parameters for HTML emails that can be sent by Bookings module
*
* @param
* @return form render array
*/
function booking_mailtemplate_form($node, &$form_state) {
global $event;
$form = array();
$header_link_max_count = 3;
$social_media_link_max_count = 3;
$prefix = "<h2>Configure HTML email template</h2>";
// load any existing values from the drupal variable table
$colors = json_decode(variable_get('booking_mailtemplate_colors'), TRUE);
$header_links = json_decode(variable_get('booking_mailtemplate_header_links'), TRUE);
$social_links = json_decode(variable_get('booking_mailtemplate_social_links'), TRUE);
//watchdog('booking_debug', "<pre>Mail template navigation links loaded\n@info</pre>", array('@info' => print_r($header_links, true)));
//watchdog('booking_debug', "<pre>Mail template social links loaded\n@info</pre>", array('@info' => print_r($social_links, true)));
$form['booking_mailtemplate_header_image_url'] = array (
'#type' => 'textfield',
'#title' => t('URL of header image'),
'#description' => t('Specify full URL to image used in header'),
'#size' => 150,
'#maxlength' => 500,
'#default_value' => empty($colors['booking_mailtemplate_header_image_url']) ? $GLOBALS['base_url'] . '/sites/all/modules/booking/images/logo.png' : $colors['booking_mailtemplate_header_image_url'],
);
$form['booking_mailtemplate_header_link_url'] = array (
'#type' => 'textfield',
'#title' => t('Destination URL for header'),
'#description' => t('Specify full URL to direct user if they click on header image'),
'#size' => 150,
'#maxlength' => 500,
'#default_value' => empty($colors['booking_mailtemplate_header_link_url']) ? $GLOBALS['base_url'] : $colors['booking_mailtemplate_header_link_url'],
);
$form['colors'] = array(
'#type' => 'fieldset',
'#title' => 'Define Colours',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['colors']['booking_mailtemplate_background_color'] = array (
'#type' => 'textfield',
'#title' => t('Background Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_background_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_background_color'],
);
$form['colors']['booking_mailtemplate_content_background_color'] = array (
'#type' => 'textfield',
'#title' => t('Content area Background Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_content_background_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_content_background_color'],
);
$form['colors']['booking_mailtemplate_header_background_color'] = array (
'#type' => 'textfield',
'#title' => t('Header area Background Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_header_background_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_header_background_color'],
);
$form['colors']['booking_mailtemplate_navigation_background_color'] = array (
'#type' => 'textfield',
'#title' => t('Navigation links area Background Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_navigation_background_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_navigation_background_color'],
);
$form['colors']['booking_mailtemplate_header_text_color'] = array (
'#type' => 'textfield',
'#title' => t('Navigation links area Text Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_header_text_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_header_text_color'],
);
$form['colors']['booking_mailtemplate_text_color'] = array (
'#type' => 'textfield',
'#title' => t('Text Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_text_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_text_color'],
);
$form['colors']['booking_mailtemplate_subjectheading_text_color'] = array (
'#type' => 'textfield',
'#title' => t('Subject Heading Text Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_subjectheading_text_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_subjectheading_text_color'],
);
/*
$form['colors']['booking_mailtemplate_link_color'] = array (
'#type' => 'textfield',
'#title' => t('Link Colour'),
'#description' => t('Specify CSS compatible value'),
'#size' => 10,
'#maxlength' => 50,
'#default_value' => empty($colors['booking_mailtemplate_link_color']) ? '#FFFFFF' : $colors['booking_mailtemplate_link_color'],
);
*/
$form['header-links'] = array(
'#type' => 'fieldset',
'#title' => 'Navigation Header Links',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
//add form elements for header links
for ($i = 1; $i <= $header_link_max_count; $i++) {
$header_link_text = 'booking_mailtemplate_headerlink_text' . $i;
$header_link_url = 'booking_mailtemplate_headerlink_url' . $i;
$form['header-links'][$header_link_text] = array(
'#type' => 'textfield',
'#title' => t('Display text for navigation header link ' . $i),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => empty($header_links[$i]['text']) ? 'Link Title' : $header_links[$i]['text'],
);
$form['header-links'][$header_link_url] = array(
'#type' => 'textfield',
'#title' => t('URL for navigation header link ' . $i),
'#size' => 150,
'#maxlength' => 500,
'#default_value' => empty($header_links[$i]['link']) ? $GLOBALS['base_url'] : $header_links[$i]['link'],
);
}
$form['social-links'] = array(
'#type' => 'fieldset',
'#title' => 'Social Media Links',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
//add form elements for social media links
for ($i = 1; $i <= $social_media_link_max_count; $i++) {
$social_link_text = 'booking_mailtemplate_sociallink_text' . $i;
$social_image_url = 'booking_mailtemplate_socialimage_url' . $i;
$social_link_url = 'booking_mailtemplate_sociallink_url' . $i;
$form['social-links'][$social_link_text] = array(
'#type' => 'textfield',
'#title' => t('Hover text for social link ' . $i),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => empty($social_links[$i]['text']) ? '' : $social_links[$i]['text'],
);
$form['social-links'][$social_image_url] = array(
'#type' => 'textfield',
'#title' => t('URL to social image ' . $i),
'#size' => 150,
'#maxlength' => 500,
'#default_value' => empty($social_links[$i]['imageurl']) ? $GLOBALS['base_url'] : $social_links[$i]['imageurl'],
);
$form['social-links'][$social_link_url] = array(
'#type' => 'textfield',
'#title' => t('URL for social link ' . $i),
'#size' => 150,
'#maxlength' => 500,
'#default_value' => empty($social_links[$i]['linkurl']) ? $GLOBALS['base_url'] : $social_links[$i]['linkurl'],
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
function booking_mailtemplate_form_submit($form, &$form_state)
{
global $event;
$color_data = array();
$header_data = array();
$social_data = array();
$values = $form_state['input'];
$colors_variable_list = array('booking_mailtemplate_background_color', 'booking_mailtemplate_content_background_color',
'booking_mailtemplate_navigation_background_color', 'booking_mailtemplate_subjectheading_text_color',
'booking_mailtemplate_header_background_color', 'booking_mailtemplate_header_text_color', 'booking_mailtemplate_text_color',
'booking_mailtemplate_header_image_url', 'booking_mailtemplate_header_link_url',
);
//'booking_mailtemplate_link_color',
//set all the values that are just using the builtin drupal variable definitions
foreach ($values as $key => $value) {
if (in_array($key, $colors_variable_list, FALSE)) {
//variable_set($key, $value);
$color_data[$key] = $value;
}
// update navigation header links
elseif (strpos($key, "booking_mailtemplate_headerlink") === 0) {
//get the ID for this header navigation link
preg_match("/.*(\d+)$/", $key, $matches);
$id = $matches[1];
$header_data[$id] = array(
'text' => $values['booking_mailtemplate_headerlink_text' . $id],
'link' => $values['booking_mailtemplate_headerlink_url' . $id],
);
}
// update social media links
elseif (strpos($key, "booking_mailtemplate_social") === 0) {
//get the ID for this header navigation link
preg_match("/.*(\d+)$/", $key, $matches);
$id = $matches[1];
$social_data[$id] = array(
'text' => $values['booking_mailtemplate_sociallink_text' . $id],
'imageurl' => $values['booking_mailtemplate_socialimage_url' . $id],
'linkurl' => $values['booking_mailtemplate_sociallink_url' . $id],
);
}
}
//watchdog('booking_debug', "<pre>Mail template navigation links\n@info</pre>", array('@info' => print_r($header_data, true)));
// store the data into the standard drupal variable table
variable_set('booking_mailtemplate_colors', json_encode($color_data));
variable_set('booking_mailtemplate_header_links', json_encode($header_data));
variable_set('booking_mailtemplate_social_links', json_encode($social_data));
}

View File

@@ -18,6 +18,7 @@ function booking_manual_payment_admin($nid)
$payment_balance_options[0] = t('Total Payment (sets total amount paid to this value)');
$payment_balance_options[1] = t('Balance Payment (adds this value to the total amount paid)');
$payment_balance_options[2] = t('Manual Refund (subtracts this value from the total amount paid)');
//collect the various payment options
$result = db_query("SELECT pid, booking_price_descrip, booking_price, booking_late_price FROM {booking_price} where booking_eventid = :eid " .
@@ -163,16 +164,26 @@ function booking_manual_payment_admin_submit($form, &$form_state) {
$person = node_load($key);
if ($person) {
// Check whether this is a balance or total payment
$payment_type = $form_state['values']['payment-balance-type'];
//check whether this is a balance or total payment
$is_balance = $form_state['values']['payment-balance-type'];
//balance payment
if ($is_balance == 1) {
// Refund
if ($payment_type == 2)
{
//subtract this payment to their existing balance
$total_paid = $person->booking_amount_paid - $price;
$invoice_type = "Refund";
}
// Balance payment
elseif ($payment_type == 1)
{
//add this payment to their existing balance
$total_paid = $person->booking_amount_paid + $price;
//total payment
} elseif ($is_balance == 0) {
$invoice_type = "ManualPayment";
}
// Total payment
elseif ($payment_type == 0)
{
//set this as the persons new balance
$total_paid = $price;
//change $price so that we add the correct dollar amount in the payment record
@@ -181,6 +192,7 @@ function booking_manual_payment_admin_submit($form, &$form_state) {
$newprice = $price - _booking_amount_paid($key, $person);
watchdog('booking', 'Changing price for payment record from $!price to !newprice.', array('!price' => $price, '!newprice' => $newprice));
$price = $newprice;
$invoice_type = "ManualPayment";
}
//check if they have now fully paid
@@ -226,7 +238,7 @@ function booking_manual_payment_admin_submit($form, &$form_state) {
'booking_mc_currency' => 'AUD',
'booking_mc_fee' => '0.00',
'booking_quantity' => 1,
'booking_invoice' => 'ManualPayment',
'booking_invoice' => $invoice_type,
'booking_payer_id' => '',
'booking_payment_date' => $payment_date,
'booking_payment_status' => '',

43
booking.misc.inc Normal file
View File

@@ -0,0 +1,43 @@
<?php
/**
* @file
* Provide a home for miscellaneous functions that don't really belong anywhere else
*/
/**
* Function for generating the "lucky number" to be used on the lanyard
*/
function booking_generate_luckynumbers() {
global $event;
$i = 0;
//query for the mappings relating to $readinggroup_studygroup_id
$attendee_query = db_query("SELECT * FROM {booking_person} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$attendees = $attendee_query->fetchAll();
//assuming there's less than 900 people, generate numbers within that range and shuffle the order
$numbers = range(100,750);
shuffle($numbers);
foreach ($attendees as $attendee)
{
$luckynum = $numbers[$i++];
drupal_set_message(t('Updating user !id to have lucky number !num.',
array('!id' => $attendee->nid, '!num' => $luckynum)));
//run an update query
db_update('booking_person')
->fields(array (
'booking_luckynum' => $luckynum,
))
->condition('nid', $attendee->nid)
->execute();
}
drupal_set_message(t('Finished.'));
return t("<h3>Generate Lucky Numbers</h3>");
}

View File

@@ -16,7 +16,9 @@
define('BOOKING_PAYPAL_SUBMIT_URL', 'https://www.paypal.com/cgi-bin/webscr');
define('BOOKING_PAYPAL_SUBMIT_URL_SANDBOX', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
//@todo should really change this to system/booking/paypal
define('BOOKING_PAYPAL_IPN_PATH', 'system/booking_paypal/ipn');
define('BOOKING_EMAIL_DEV_NOTIFY', 'it@coadcorp.com');
// Load the include for various constants
module_load_include('inc', 'booking', 'booking.constants');
@@ -39,7 +41,7 @@ module_load_include('inc', 'booking', 'booking.admin');
// Load the include for admin pages relating to events
module_load_include('inc', 'booking', 'booking.events');
// Load the include for admin pages relating to event pricing
module_load_include('inc', 'booking', 'booking.prices');
//module_load_include('inc', 'booking', 'booking.prices');
// Load the include for admin pages relating to manual processing of payments
module_load_include('inc', 'booking', 'booking.manual_payment');
// Load the include for helper functions
@@ -48,10 +50,13 @@ module_load_include('inc', 'booking', 'booking.helper');
module_load_include('inc', 'booking', 'booking.paypal');
// Load the include for email functions
module_load_include('inc', 'booking', 'booking.emails');
module_load_include('inc', 'booking', 'booking.emails_admin');
module_load_include('inc', 'booking', 'booking.email_manually');
// Load the include for bulk data import
module_load_include('inc', 'booking', 'booking.import_data');
// Load the include for variety session configuration
module_load_include('inc', 'booking', 'booking.variety');
module_load_include('inc', 'booking', 'booking.variety_form');
module_load_include('inc', 'booking', 'booking.variety_admin');
// Load the include for study group configuration
module_load_include('inc', 'booking', 'booking.studygroups');
// Load the include for study group definitions
@@ -66,12 +71,18 @@ module_load_include('inc', 'booking', 'booking.rooms');
module_load_include('inc', 'booking', 'booking.rooms_allocate');
// Load the include for room layout definitions
module_load_include('inc', 'booking', 'booking.rooms_admin');
// Load the include for stripe payments
module_load_include('inc', 'booking', 'booking.stripe');
// Load the include for miscellaneous functions
module_load_include('inc', 'booking', 'booking.misc');
// Load the include for the extended mail system
//module_load_include('inc', 'booking', 'booking.MailSystemInterface');
function booking_init() {
date_default_timezone_set(date_default_timezone(FALSE));
global $event;
//reference - http://www.devdaily.com/drupal/drupal-7-sql-cheat-sheet-function-examples
//@see http://www.devdaily.com/drupal/drupal-7-sql-cheat-sheet-function-examples
$event = db_query("SELECT * from {booking_event} where booking_event_active=1")
->fetchObject();
@@ -81,7 +92,6 @@ function booking_init() {
/**
* Implementation of hook_permission().
* D7 done.
*/
function booking_permission() {
return array(
@@ -124,8 +134,17 @@ function booking_permission() {
'edit room allocations' => array(
'title' => t('Edit Room Allocations'),
),
'create_travel_forms' => array(
'title' => t('Create a new travel form entry'),
'access variety session form' => array(
'title' => t('Access the Variety Session registration form'),
),
'view variety sessions' => array(
'title' => t('View Variety Sessions'),
),
'edit variety sessions' => array(
'title' => t('Edit Variety Sessions'),
),
'create travel entry' => array(
'title' => t('Create a travel entry'),
),
'view_travel_forms' => array(
'title' => t('View all travel forms'),
@@ -148,14 +167,6 @@ function booking_menu() {
$items = array();
$items['admin/config/booking'] = array(
/*
'title' => 'Booking module configuration',
'description' => 'Configure the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_admin'),
'access arguments' => array('access administration pages'),
*/
'title' => 'Booking module configuration',
'description' => 'Configure the Booking module',
'position' => 'left',
@@ -165,11 +176,8 @@ function booking_menu() {
'file' => 'system.admin.inc',
'file path' => drupal_get_path('module', 'system'),
//'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/booking/general'] = array(
'title' => 'Booking module general configuration',
'description' => 'Configure general settings for Booking module',
'page callback' => 'drupal_get_form',
@@ -179,40 +187,74 @@ function booking_menu() {
//'position' => 'left',
'weight' => -100,
);
//http://www.akchauhan.com/create-drupal-form-using-theme_table-like-module-list-form/
$items['admin/config/booking/text'] = array(
'title' => 'Booking module text definitions',
'description' => 'Configure text used in the Event Booking module',
'description' => 'Configure text used in the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_tokens_admin'),
'access arguments' => array('administer site configuration'),
'weight' => -99,
//'type' => MENU_LOCAL_TASK,
);
$items['admin/config/booking/emails'] = array(
'title' => 'Booking module workflow email definitions',
'description' => 'Configure built-in workflow emails used by the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_emails_workflow_admin'),
'access arguments' => array('access administration pages'),
'file' => 'booking.emails_admin.inc',
'weight' => -98,
//'type' => MENU_LOCAL_TASK,
);
$items['admin/config/booking/emails/definitions'] = array(
'title' => 'Booking module custom email definitions',
'description' => 'Configure custom emails used by the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_emails_custom_ajax_form'),
'access arguments' => array('access administration pages'),
'file' => 'booking.emails_admin.inc',
'type' => MENU_LOCAL_ACTION,
);
/*
$items['admin/config/booking/emails/custom'] = array(
'title' => 'Booking module custom email definitions',
'description' => 'Configure custom emails used by the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_emails_custom_admin'),
'access arguments' => array('access administration pages'),
'file' => 'booking.emails_admin.inc',
'type' => MENU_LOCAL_ACTION,
);
$items['admin/config/booking/emails/logistics'] = array(
'title' => 'Booking module custom logistics email definitions',
'description' => 'Configure custom logistics emails used by the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_emails_customlogistics_admin'),
'access arguments' => array('access administration pages'),
'file' => 'booking.emails_admin.inc',
'type' => MENU_LOCAL_ACTION,
);
*/
$items['admin/config/booking/events'] = array(
'title' => 'Booking module event settings',
'description' => 'Configure events for the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_event_admin'),
'access arguments' => array('administer site configuration'),
'weight' => -97,
'file' => 'booking.events.inc',
//'type' => MENU_LOCAL_TASK,
);
$items['admin/config/booking/prices'] = array(
'title' => 'Booking module price settings',
'description' => 'Configure prices for the Event Booking module',
'description' => 'Configure prices for the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_price_admin'),
'access arguments' => array('administer site configuration'),
//'type' => MENU_LOCAL_TASK,
);
$items['admin/config/booking/events'] = array(
'title' => 'Booking module event settings',
'description' => 'Configure events for the Event Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_event_admin'),
'access arguments' => array('administer site configuration'),
//'type' => MENU_LOCAL_TASK,
);
$items['admin/config/booking/variety'] = array(
'title' => 'Booking module variety sessions',
'description' => 'Configure variety sessions for the Event Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_admin'),
'access arguments' => array('administer site configuration'),
'weight' => -96,
'file' => 'booking.prices.inc',
//'type' => MENU_LOCAL_TASK,
);
@@ -232,11 +274,12 @@ function booking_menu() {
'access arguments' => array('access booking form'),
'type' => MENU_NORMAL_ITEM,
);
$items['bookingfinal'] = array(
'title' => $bookingTitle . ' Registration Completed',
'page callback' => 'booking_payment_completed_page',
'access arguments' => array('access booking form'),
'type' => MENU_NORMAL_ITEM,
'type' => MENU_CALLBACK,
);
$items['confirm/%'] = array(
'title' => 'Booking Payment',
@@ -266,8 +309,31 @@ function booking_menu() {
'title' => 'Travel Details Page',
'page callback' => 'booking_travel_page',
'page arguments' => array(3), //include the temporary id
'access arguments' => array('access booking form'),
'access arguments' => array('create travel entry'),
'type' => MENU_SUGGESTED_ITEM,
'file' => 'booking.travel.inc',
);
$items['coming'] = array(
'title' => "Who's Coming?",
'page callback' => 'booking_coming_page',
'access arguments' => array("access coming list"),
'type' => MENU_NORMAL_ITEM,
);
//callback for autocomplete lookup of ecclesia name
$items['booking/ecclesia/autocomplete'] = array(
'title' => 'Autocomplete for ecclesia lookup on registration page',
'page callback' => '_booking_ecclesia_name_autocomplete',
'access arguments' => array('access booking form'),
'type' => MENU_CALLBACK
);
$items['waitinglist'] = array(
'title' => "Who's on the waiting list?",
'page callback' => 'booking_waitinglist_page',
'access arguments' => array("access waiting list"),
'type' => MENU_NORMAL_ITEM,
);
//Various reports
@@ -287,11 +353,21 @@ function booking_menu() {
'type' => MENU_NORMAL_ITEM,
);
$items['admin/booking/travel'] = array(
'title' => 'Booking Travel Summary',
'description' => "List people's travel details",
'page callback' => 'booking_report_travel',
'access arguments' => array('access reports'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/booking/manual-email'] = array(
'title' => 'Manually Email People',
'description' => 'Send manual email to registered people',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_manual_email'),
'page arguments' => array('booking_manual_email_form'),
//'page callback' => 'drupal_get_form',
//'page arguments' => array('booking_manual_email'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
@@ -322,24 +398,9 @@ function booking_menu() {
'type' => MENU_NORMAL_ITEM,
);
$items['coming'] = array(
'title' => "Who's Coming?",
'page callback' => 'booking_coming_page',
'access arguments' => array("access coming list"),
'type' => MENU_NORMAL_ITEM,
);
$items['waitinglist'] = array(
'title' => "Who's on the waiting list?",
'page callback' => 'booking_waitinglist_page',
'access arguments' => array("access waiting list"),
'type' => MENU_NORMAL_ITEM,
);
//show flight info report only if we have passport info enabled
if (variable_get('booking_enable_passport', 0) == 1)
{
//now deprecated
if (variable_get('booking_enable_passport', 0) == 1) {
$items['admin/booking/flights'] = array(
'title' => 'Booking View Flights',
'description' => 'View Internal Flight Bookings',
@@ -349,69 +410,100 @@ function booking_menu() {
);
}
if (variable_get('booking_enable_variety_sessions', 0) == 1)
{
if (variable_get('booking_enable_variety_sessions', 0) == 1) {
$items['variety'] = array(
'title' => $bookingTitle . ' Variety Sessions',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_regn_form'),
'access arguments' => array('access booking form'),
'access arguments' => array('access variety session form'),
'type' => MENU_NORMAL_ITEM,
);
//configure variety sessions
$items['admin/config/booking/variety/create'] = array(
$items['admin/booking/variety'] = array(
'title' => 'View Variety Sessions',
'description' => 'View variety sessions for the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_admin'),
'access arguments' => array('edit variety sessions'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/booking/variety/create'] = array(
'title' => 'Add New Variety Session Timeslot',
'description' => 'Add variety session timeslot for the Booking module',
'page callback' => 'drupal_get_form',
//'page arguments' => array('booking_price_create'),
'page arguments' => array('booking_variety_timeslot_form', true),
'access arguments' => array('access administration pages'),
'access arguments' => array('edit variety sessions'),
'type' => MENU_LOCAL_ACTION,
);
$items['admin/config/booking/variety/%/edit'] = array(
$items['admin/booking/variety/report'] = array(
'title' => 'View Variety Session Registrations',
'description' => 'View Variety Session Registrations for the Booking module',
'page callback' => 'booking_variety_sessions_view_summary',
'access arguments' => array('view variety sessions'),
'type' => MENU_LOCAL_ACTION,
);
$items['admin/booking/variety/%/edit'] = array(
'title' => 'Edit Variety Session Timeslot',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_timeslot_form', false, 4),
'access arguments' => array('access administration pages'),
'page arguments' => array('booking_variety_timeslot_form', false, 3),
'access arguments' => array('edit variety sessions'),
'type' => MENU_CALLBACK,
);
$items['admin/config/booking/variety/%/session/list'] = array(
$items['admin/booking/variety/%/csv'] = array(
'title' => 'Variety Session CSV',
'description' => 'CSV Report of Variety Session Timeslot',
'page callback' => 'booking_varietysessions_csv_report',
'access arguments' => array('view variety sessions'),
'page arguments' => array(3),
//'type' => MENU_CALLBACK,
);
$items['admin/booking/variety/%/session/list'] = array(
'title' => 'List Variety Sessions',
'description' => 'List variety sessions for the specified timeslot',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_list_session_form', 4),
'access arguments' => array('access administration pages'),
'page arguments' => array('booking_variety_list_session_form', 3),
'access arguments' => array('view variety sessions'),
'type' => MENU_CALLBACK,
);
$items['admin/config/booking/variety/%/session/create'] = array(
$items['admin/booking/variety/%/session/create'] = array(
'title' => 'Add New Variety Session',
'description' => 'Add variety session to the specified timeslot',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_create_session_form', 4),
'access arguments' => array('access administration pages'),
'page arguments' => array('booking_variety_create_session_form', TRUE, 3),
'access arguments' => array('edit variety sessions'),
'type' => MENU_CALLBACK,
);
$items['admin/config/booking/variety/session/%/edit'] = array(
$items['admin/booking/variety/%/session/%/edit'] = array(
'title' => 'Edit Variety Session',
'description' => 'Edit variety session for the specified timeslot',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_edit_session_form', 5),
'access arguments' => array('access administration pages'),
'page arguments' => array('booking_variety_create_session_form', FALSE, 3, 5),
'access arguments' => array('edit variety sessions'),
'type' => MENU_CALLBACK,
);
$items['admin/booking/variety/registration/%/edit'] = array(
'title' => 'Edit Variety Session Registration',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_variety_regn_edit_form', 4),
'access arguments' => array('edit variety sessions'),
'type' => MENU_CALLBACK,
);
}
//configure study groups
if (variable_get('booking_enable_studygroups', 0) == 1)
{
if (variable_get('booking_enable_studygroups', 0) == 1) {
//the config pages for study groups
$items['admin/config/booking/studygroups'] = array(
'title' => 'Booking Module Study Group Configuration',
'title' => 'Booking module Study Group configuration',
'description' => 'Define and configure Study Groups for the Booking module',
'page callback' => 'booking_studygroups_admin',
'access arguments' => array('administer site configuration'),
@@ -454,6 +546,16 @@ function booking_menu() {
'type' => MENU_NORMAL_ITEM,
);
//@todo a nice report with everyone's studygroup membership
$items['admin/booking/studygroups/report/leadershelpers'] = array(
'title' => 'View Studygroup Leaders and Helpers',
'description' => 'View Studygroup Leaders and Helpers',
'page callback' => 'booking_studygroups_leadhelp_view_summary',
'access arguments' => array("view study groups"),
'type' => MENU_LOCAL_ACTION,
);
$items['admin/booking/studygroups/calculateleaders'] = array(
'title' => 'Calculate Study Group Leaders',
'description' => 'Calculate Study Group Leaders and Helpers',
@@ -497,16 +599,23 @@ function booking_menu() {
'access arguments' => array('edit study groups'),
//'type' => MENU_LOCAL_ACTION,
);
/*
$items['admin/booking/studygroups/calculate'] = array(
'title' => 'Calculate Study Groups',
'description' => 'Calculate Study Group memberships',
$items['admin/booking/studygroups/%/editleaders'] = array(
'title' => 'Edit Study Group Leaders',
'description' => 'Edit Study Group Leaders and Helpers',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_studygroups_calculate'),
'page arguments' => array('booking_studygroup_leadhelp_edit_form', 3),
'access arguments' => array('edit study groups'),
'type' => MENU_LOCAL_ACTION,
//'type' => MENU_LOCAL_ACTION,
);
*/
//callback for autocomplete lookup
$items['booking/studygroups/autocomplete'] = array(
'title' => 'Autocomplete for studygroup allocations',
'page callback' => '_booking_studygroups_name_autocomplete',
'access arguments' => array('edit study groups'),
'type' => MENU_CALLBACK
);
$items['admin/booking/studygroups/%/update'] = array(
'title' => 'Update Study Groups',
'description' => 'Calculate updated Study Group memberships',
@@ -533,7 +642,7 @@ function booking_menu() {
//config pages
$items['admin/config/booking/rooms'] = array(
'title' => 'Booking module room definitions',
'description' => 'View and Configure room definitions for the Event Booking module',
'description' => 'View and configure Room Definitions for the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_rooms_view_definitions'),
'access arguments' => array('administer site configuration'),
@@ -585,8 +694,8 @@ function booking_menu() {
);
$items['admin/booking/rooms/report'] = array(
'title' => 'View All Room Allocations',
'description' => 'View All Room Allocations',
'title' => 'View Room Mate Preferences and Room Allocations',
'description' => 'View Room Mate Preferences and Room Allocations',
'page callback' => 'booking_roomallocations_view_summary',
'access arguments' => array("view room allocations"),
'type' => MENU_LOCAL_ACTION,
@@ -646,6 +755,7 @@ function booking_menu() {
'page arguments' => array('booking_price_form', true),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_ACTION,
'file' => 'booking.prices.inc',
);
$items['admin/config/booking/prices/%/edit'] = array(
@@ -654,6 +764,7 @@ function booking_menu() {
'page arguments' => array('booking_price_form', false, 4),
'access arguments' => array('access administration pages'),
'type' => MENU_CALLBACK,
'file' => 'booking.prices.inc',
);
//Configure events
@@ -664,6 +775,7 @@ function booking_menu() {
'page arguments' => array('booking_event_form', true),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_ACTION,
'file' => 'booking.events.inc',
);
$items['admin/config/booking/events/%/edit'] = array(
@@ -674,22 +786,67 @@ function booking_menu() {
'page arguments' => array('booking_event_form', false, 4),
'access arguments' => array('access administration pages'),
'type' => MENU_CALLBACK,
'file' => 'booking.events.inc',
);
//manage early access codes
$items['admin/config/booking/earlyaccess'] = array(
'title' => 'Booking module Early Access Codes',
'description' => 'Define and configure Early Access Codes for the Booking module',
'page callback' => 'booking_earlyaccess_admin',
'access arguments' => array('access administration pages'),
'file' => 'booking.earlyaccess_admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/booking/earlyaccess/generate'] = array(
'title' => 'Generate Early Access Codes',
'description' => 'Generate Early Access Codes',
'page callback' => 'booking_earlyaccess_generate_codes',
'access arguments' => array('access administration pages'),
'file' => 'booking.earlyaccess_admin.inc',
'type' => MENU_LOCAL_ACTION,
);
$items['admin/config/booking/earlyaccess/csv'] = array(
'title' => 'Download Early Access Codes CSV',
'description' => 'Download Early Access Codes CSV',
'page callback' => 'booking_earlyaccess_csv_report',
'access arguments' => array('access administration pages'),
'file' => 'booking.earlyaccess_admin.inc',
'type' => MENU_LOCAL_ACTION,
);
//manage HTML email template if enabled
if (variable_get('booking_enable_html_mail', 0) == 1) {
$items['admin/config/booking/mailtemplate'] = array(
'title' => 'Booking module HTML email',
'description' => 'Configure the look of HTML emails for the Booking module',
'page callback' => 'drupal_get_form',
'page arguments' => array('booking_mailtemplate_form'),
'access arguments' => array('access administration pages'),
'file' => 'booking.mailtemplate_admin.inc',
'type' => MENU_NORMAL_ITEM,
);
}
//the paypal IPN
$items[BOOKING_PAYPAL_IPN_PATH] = array(
'type' => MENU_CALLBACK,
'access callback' => TRUE,
'page callback' => 'booking_paypal_ipn',
'access callback' => TRUE
);
//stripe webhook
$items['system/booking/stripe/webhook'] = array(
'type' => MENU_CALLBACK,
'access callback' => TRUE,
'page callback' => 'booking_stripe_webhook',
);
return $items;
}
/**
* Describe the nodes we are going to define to model content specific to the booking module
* D7 done
*/
function booking_node_info() {
return array(
@@ -706,7 +863,6 @@ function booking_node_info() {
);
}
/**
* Implementation of access related hooks for booking_registration node type.
*/
@@ -718,14 +874,12 @@ function booking_node_access($node, $op, $account) {
//watchdog('booking', "Booking node_access processing user id '!account' performing operation !op for node type !type. @info",
// array('!account' => $account->uid, '!op' => $op, '!type' => $type, '@info' => var_export($account, TRUE)));
if ($op == 'view')
{
if ($op == 'view') {
//watchdog('booking', 'Booking node_access checking permissions for view operation.');
if (user_access('view bookings', $account))
return NODE_ACCESS_ALLOW;
}
elseif ($op == 'create')
{
elseif ($op == 'create') {
//watchdog('booking', 'Booking node_access checking permissions for create operation.');
if (user_access('create bookings', $account))
return NODE_ACCESS_ALLOW;
@@ -734,8 +888,7 @@ function booking_node_access($node, $op, $account) {
else
return NODE_ACCESS_DENY;
}
elseif ($op == 'update' || $op == 'delete')
{
elseif ($op == 'update' || $op == 'delete') {
if (user_access('edit bookings', $account))
return NODE_ACCESS_ALLOW;
}
@@ -748,20 +901,16 @@ function booking_node_access($node, $op, $account) {
return NODE_ACCESS_DENY;
}
//Check access levels for travel form node
elseif ($type == 'travel' && in_array($type, node_permissions_get_configured_types()))
{
if ($op == 'view')
{
elseif ($type == 'travel' && in_array($type, node_permissions_get_configured_types())) {
if ($op == 'view') {
if (user_access('view_travel_forms', $account))
return NODE_ACCESS_ALLOW;
}
elseif ($op == 'create')
{
elseif ($op == 'create') {
if (user_access('create_travel_forms', $account))
return NODE_ACCESS_ALLOW;
}
elseif ($op == 'update' || $op == 'delete')
{
elseif ($op == 'update' || $op == 'delete') {
if (user_access('edit_travel_forms', $account))
return NODE_ACCESS_ALLOW;
}
@@ -783,16 +932,38 @@ function booking_node_access($node, $op, $account) {
}
/**
* Implementation of hook_theme().
*/
function booking_theme() {
function booking_theme($existing, $type, $theme, $path) {
if($type == 'module') {
$theme_path = drupal_get_path('module', 'booking'). '/theme';
// if our more heavily customised template exists, use that, otherwise fall back to the generic one
$template_file = is_file($theme_path . '/mimemail-message-registration_mail.tpl.php') ? '/mimemail-message-registration_mail' : '/mimemail-message';
return array(
'booking_details' => array('arguments' => array('node' => NULL)),
//'booking_price_admin' => array('arguments' => array('form' => NULL))
'booking_htmlmail_template' => array(
'variables' => array('module' => NULL, 'key' => NULL, 'css' => NULL, 'recipient' => NULL, 'subject' => NULL, 'body' => NULL, 'message' => array()),
'path' => $theme_path,
'template' => 'mimemail-message' // extension of .tpl.php automatically added
),
'booking_htmlmail_registration_mail' => array(
'variables' => array('subject' => NULL,
'body' => NULL,
'footer' => NULL,
'colors' => NULL,
'header_links' => NULL,
'social_links' => NULL,
),
'path' => $theme_path,
//'image_path' => drupal_get_path('module', 'booking'). '/images',
'template' => $template_file,
),
);
}
return array(); //will raise fatal error if void
}
/**
* Add custom templates to the list of theme hooks
@@ -819,48 +990,138 @@ function booking_mail($key, &$message, $params) {
$message['headers'] += $params['headers'];
}
// Add attachment when available.
// From https://drupal.stackexchange.com/questions/101035/send-attachments-with-drupal-mail
if (isset($params['attachment'])) {
$message['params']['attachments'] = $params['attachment'];
}
//watchdog('booking_debug', "<pre>Mail hook:\n@info</pre>", array('@info' => print_r( $message, true)));
}
/**
* Function for generating the "lucky number" to be used on the lanyard
* Implements hook_mail_alter()
*/
function booking_generate_luckynumbers() {
global $event;
$i = 0;
//query for the mappings relating to $readinggroup_studygroup_id
$attendee_query = db_query("SELECT * FROM {booking_person} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$attendees = $attendee_query->fetchAll();
//assuming there's less than 900 people, generate numbers within that range and shuffle the order
$numbers = range(100,650);
shuffle($numbers);
foreach ($attendees as $attendee)
{
$luckynum = $numbers[$i++];
drupal_set_message(t('Updating user !id to have lucky number !num.',
array('!id' => $attendee->nid, '!num' => $luckynum)));
//run an update query
db_update('booking_person')
->fields(array (
'booking_luckynum' => $luckynum,
))
->condition('nid', $attendee->nid)
->execute();
function booking_mail_alter(&$message) {
//message id used here comes from {module_name}_{email_key}
$implemented_message_ids = array('booking_registration_mail', 'booking_registration_mail_notify', 'booking_booking_email_custom', 'booking_registration_mail_bal_outstanding');
if (in_array($message['id'], $implemented_message_ids)) {
//watchdog('booking_debug', "Message key matched in booking_mail_alter, setting to html email.");
$headers = array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => '8bit',
'X-Mailer' => 'Drupal',
);
}else{
$headers = array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
'Content-Transfer-Encoding' => '8bit',
'X-Mailer' => 'Drupal',
);
}
drupal_set_message(t('Finished.'));
return t("<h3>Generate Lucky Numbers</h3>");
//Overwrite header message header with Content-Type accommodating for html format
foreach($headers as $key => $value) {
$message['headers'][$key] = $value;
}
//watchdog('booking_debug', "<pre>Mail alter hook:\n@info</pre>", array('@info' => print_r( $message, true)));
}
/**
* Implements hook_library().
*/
function booking_library() {
$module_path = drupal_get_path('module', 'booking');
$items['booking-stripe'] = array(
'title' => t('Stripe'),
'version' => '1.0',
'js' => array(
//'https://js.stripe.com/v1/' => array(),
'https://checkout.stripe.com/checkout.js' => array(),
$module_path . '/booking.stripe.js' => array(),
),
);
return $items;
}
/**
* Implements hook_libraries_info().
*/
function booking_libraries_info() {
$libraries['stripe'] = array(
'name' => 'Stripe Payment API PHP Library',
'vendor url' => 'https://github.com/stripe/stripe-php',
'download url' => 'https://github.com/stripe/stripe-php/archive/master.zip',
'version arguments' => array(
'file' => 'VERSION',
'pattern' => '/([0-9a-zA-Z\.-]+)/',
'lines' => 1,
),
'files' => array('php' => array('init.php')),
'callbacks' => array('post-load' => array('booking_libraries_postload_callback')),
);
return $libraries;
}
/**
* Post-load callback for the Stripe PHP Library.
*
* @param array $library
* An array of library information.
* @param string $version
* If the $library array belongs to a certain version, a string containing the
* version.
* @param string $variant
* If the $library array belongs to a certain variant, a string containing the
* variant name.
*/
function booking_libraries_postload_callback($library, $version = NULL, $variant = NULL) {
if (!empty($library['loaded'])) {
\Stripe\Stripe::setApiKey(_booking_get_stripe_private_key());
}
}
/**
* Implements hook_requirements().
*/
function booking_requirements($phase) {
$requirements = array();
$t = get_t();
//do a runtime verification that the stripe library is installed
if ($phase == 'runtime') {
//check that the stripe library is present
if (($library = libraries_detect('stripe')) && !empty($library['installed'])) {
// The library is installed. Awesome!
$info = libraries_info('stripe');
//watchdog('booking_debug', "<pre>Stripe library check\n@info</pre>", array('@info' => print_r($info, true)));
$requirements['booking_stripe_library'] = array(
'title' => $t('Booking Module Libraries'),
'description' => $t('Stripe library is installed.'),
'value' => $t('Version !version installed.', array('!version' => $info['version'])),
'severity' => REQUIREMENT_OK,
);
}
else {
// Stripe library is not installed or something else is wrong with it
$error_message = $library['error message'];
$requirements['booking_stripe_library'] = array(
'title' => $t('Booking Module Libraries'),
'description' => $t('Stripe payment processor library not installed correctly. Download https://github.com/stripe/stripe-php/archive/master.zip and extract contents into sites/all/libraries/stripe'),
'value' => $error_message,
'severity' => REQUIREMENT_ERROR,
);
}
}
return $requirements;
}
/*
function booking_form_user_profile_form_alter(&$form, &$form_state) {
// Add your own function to the array of validation callbacks

View File

@@ -1,5 +1,34 @@
<?php
/**
* Helper function to calculate paypal fees
*/
function _booking_add_paypal_fees($amount, $country)
{
//add the 30 cent fixed cost
$result = '0.00';
$result = (float) ($amount + (float) variable_get('booking_paypal_transaction_fee_fixedcost', '0.3'));
//and the 2.6 percent transaction fee for australian transaction with no currency conversion
if ($country == variable_get('booking_default_country', 'Australia')) {
$percentage = (float) variable_get('booking_paypal_transaction_fee_percentage', '2.6');
} else {
$percentage = (float) variable_get('booking_paypal_transaction_fee_percentage_intl', '3.6');
//watchdog('booking', "Calculating paypal fees for a currency conversion transaction which adds $percentage percent.");
}
//apply the percentage
$percentage = (float) $percentage / 100;
//watchdog('booking', "Paypal percentage transaction fee works out to $percentage.");
$result = $result / (1 - $percentage);
//return result
return $result;
}
/**
* Helper function to generate string to post to paypal to verify a successful IPN
*/
function _booking_paypal_post($data = array()) {
$post = '';
foreach ($data as $key => $value) {
@@ -10,7 +39,10 @@ function _booking_paypal_post($data = array()) {
return $post;
}
//see https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php for more details
/**
* Helper function to verify a successful IPN from Paypal
* @see https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php
*/
function _booking_paypal_ipn_verify($vars = array()) {
if (variable_get('booking_paypal_sandbox', 0)) {
@@ -91,7 +123,7 @@ function booking_paypal_ipn() {
}
*/
//TODO: Handle refund and payment dispute IPNs
//@todo Handle refund and payment dispute IPNs
if (empty($ipn['payment_status']) || ($ipn['payment_status'] != 'Completed' && variable_get('booking_paypal_sandbox', 0) == 0))
return;
@@ -104,19 +136,18 @@ function booking_paypal_ipn() {
}
//Insert record into database and remove temporary booking id field from user
_booking_process_payment($ipn);
_booking_store_paypal_payment($ipn);
}
function _booking_process_payment($data) {
function _booking_store_paypal_payment($data) {
global $event;
$balance_payment = false;
$amount_owing = 0;
//extract the person node id from the invoice
$pos = strpos($data['invoice'], "_");
if (($pos === false) || ($pos == 0))
{
if (($pos === false) || ($pos == 0)) {
watchdog('booking', 'Unable to process payment with invalid invoice information: !id', array('!id' => $data['invoice']), WATCHDOG_ERROR);
return;
}
@@ -125,19 +156,15 @@ function _booking_process_payment($data) {
//get the data between the first and second underscore
$eid = substr($data['invoice'], $pos + 1, strrpos($data['invoice'], "_") - $pos - 1);
if (substr($eid,0,3) == "bal")
{
if (substr($eid,0,3) == "bal") {
$balance_payment = true;
watchdog('booking', 'Balance payment for user with node id: !id', array('!id' => $nid));
}
//verify paypal hasn't already sent through a notification for this payment
$duplicate_check = db_query("SELECT payid, booking_person_nid FROM {booking_payment} where booking_ipn_track_id = :ipn_id ",
array(':ipn_id' => $data['ipn_track_id']))
->fetchObject();
if ($duplicate_check)
{
array(':ipn_id' => $data['ipn_track_id']))->fetchObject();
if ($duplicate_check) {
watchdog('booking', 'Detected duplicate paypal notifications for transaction id !id, registration id !nid', array('!id' => $data['ipn_track_id'], '!nid' => $nid), WATCHDOG_ERROR);
return;
}
@@ -165,135 +192,117 @@ function _booking_process_payment($data) {
))
->execute();
//Get the person's info
//Get the person's info so we can update their total amount paid and booking status
$person = node_load($nid);
//check if we found a person matching this payment
if ($person)
{
watchdog('booking', 'Found matching user with node id: !id; event id: !eid; existing payment !payment', array('!id' => $nid, '!eid' => $eid,
'!payment' => $person->booking_amount_paid));
//if successful, update their total payment amount
$total = $person->booking_amount_paid + $data['mc_gross'];
//only recalculate their booking status if this is the initial payment, not a payment of the outstanding balance
if ($balance_payment == FALSE)
{
watchdog('booking', 'Processing an initial payment. Booking status is currently ' . $person->booking_status);
if ($person->booking_status == 1)
{
watchdog('booking', 'This registration has been manually assigned to the booked-in list.');
$status = 1;
if ($person) {
watchdog('booking', 'Found matching user with node id: !id; event id: !eid; existing payment !payment',
array('!id' => $nid, '!eid' => $eid, '!payment' => $person->booking_amount_paid));
_booking_process_person_payment($person, $data['mc_gross'], $balance_payment);
}
elseif (_booking_check_bookings_full() == True || $person->booking_status == 2)
{
watchdog('booking', 'This registration belongs on the waiting list.');
$status = 2;
}
else
{
watchdog('booking', 'This registration made it to the booked-in list.');
$status = 1;
}
}
else //this is a balance payment
{
watchdog('booking', 'Processing a balance payment.');
//if this is a payment of outstanding balance, keep the booking_status the same
$status = $person->booking_status;
//$status = $person->booking_status == 2 ? 2 : 1;
}
//update the database for this person
db_update('booking_person')
->fields(array(
'booking_amount_paid' => $total,
'booking_status' => $status,
))
->condition('nid', $nid)
->execute();
//replace the code below with a call to the helper function
_booking_postpayment_trigger($nid, $person, $balance_payment);
/*
//If there is no outstanding balance, send a payment complete email
$amount_owing = _booking_amount_owing($person);
//if ($total >= $person->booking_total_pay_reqd)
if ($amount_owing == 0)
{
//set the payment complete flag
db_update('booking_person')
->fields(array(
'booking_payment_complete' => 'Y',
))
->condition('nid', $nid)
->execute();
//this should always be a balance payment type email, since that tells the user that their payment is completed
_booking_registration_email($nid, TRUE);
//if we are combining payments, and this person has a linked spouse
if ((variable_get('booking_enable_combined_pricing', 0) == 1) && ($person->booking_partner_id > 0))
{
//check spouse booking_status and payment info
$spouse = db_select('booking_person', 'p')
->condition('p.nid', $person->booking_partner_id,'=')
->fields('p', array('booking_amount_paid', 'booking_status', 'booking_total_pay_reqd'))
->execute()
->fetchObject();
//update the spouse's status from "not paid" if required
$spouse_status = $spouse->booking_status == 0 ? 1 : $spouse->booking_status;
watchdog('booking', 'Setting status for spouse id !id to !new from !status', array('!id' => $person->booking_partner_id,
'!new' => $spouse_status, '!status' => $spouse->booking_status));
//set the spouse's payment required to be zero or equal to their previous payment total
$spouse_new_amount_reqd = $spouse->booking_amount_paid > 0 ? $spouse->booking_amount_paid : 0;
watchdog('booking', 'Setting amount owing for spouse id !id to !new from !old.', array('!id' => $person->booking_partner_id,
'!new' => $spouse_new_amount_reqd, '!old' => $spouse->booking_total_pay_reqd));
//update the database for this person
db_update('booking_person')
->fields(array(
'booking_total_pay_reqd' => $spouse_new_amount_reqd,
'booking_status' => $spouse_status,
'booking_payment_complete' => 'Y',
))
->condition('nid', $person->booking_partner_id)
->execute();
//send an email to the spouse
_booking_registration_email($person->booking_partner_id, TRUE);
}
}
//if this was an initial payment we might need to send a notification
elseif ($balance_payment == FALSE)
{
//send a notification email if we didn't automatically send one earlier
if (variable_get('booking_auto_confirm_email', 0) == 0)
{
_booking_registration_email($nid, FALSE);
}
}
else //this person still has an outstanding balance so just send a confirmation email
{
watchdog('booking', 'This balance payment of !payment was insufficient for !id to completely pay the total outstanding of !outstanding.',
array('!id' => $nid, '!payment' => $data['mc_gross'], '!outstanding' => $amount_owing));
//send the person an email thanking them for their partial payment
_booking_partialbalance_payment_email($nid);
//TODO: create an email specifically for partial-balance payments
//_booking_registration_email($nid, $balance_payment);
}
*/
}
else //couldn't find a matching nid for this invoice
{
else {
//couldn't find a matching nid for this invoice
watchdog('booking', "Unable to process payment for user with node id: '!id'", array('!id' => $nid), WATCHDOG_ERROR);
//db_query("UPDATE {booking_person} SET booking_tempid='' WHERE nid = %d", $nid);
}
}
/**
* Landing page after returning from paypal
*/
function booking_payment_completed_page() {
//get some configuration information
global $event;
$output = "";
$return_array = array();
/*
$parameters = drupal_get_query_parameters();
//check if we got a transaction token from paypal
if (isset($parameters['token'])) {
//check to make sure the value is something we're expecting
$paypal_token = $parameters['token'];
if (! preg_match('/^[0-9A-Fa-f\-]+$/', $paypal_token)) {
//parameter from url is not what we were expecting so ignore it and just use the site-wide tokens for this page
$tokens = booking_define_tokens();
}
else {
//query the payments table to find the attendee that this paypal token belongs to
}
}
*/
//set the page title
$bookingTitle = !empty($event->booking_eventname) ? $event->booking_eventname : 'Event';
drupal_set_title($bookingTitle . ' Registration Completed');
$input = variable_get('booking_regn_completed_page');
//watchdog('booking_debug', "<pre>Paypal landing page token:\n@info</pre>", array('@info' => print_r($input['value'] , true)));
$output = token_replace($input['value'], booking_define_tokens());
$return_array[] = array(
'paragraph' => array(
'#type' => 'markup',
'#markup' => $output
)
);
return $return_array;
}
/**
* Helper function to generate paypal form for payments
*/
function _booking_paypal_form($person, $invoiceid, $amount_owing, $button_text) {
$form = drupal_get_form('_booking_paypal_form_builder', $person, $invoiceid, $amount_owing, $button_text);
return drupal_render($form);
}
/**
* Helper function to generate form elements for paypal form
*/
function _booking_paypal_form_builder($node, &$form_state, $person, $invoiceid, $amount_owing, $button_text) {
global $event;
//get our current path so we can send the user back here if they cancel
$path = isset($_GET['q']) ? $_GET['q'] : '<front>';
//paypal specific settings
$vars = array(
'module' => 'Booking System',
'type' => $event->booking_eventname,
//'custom' => $data,
'item_name' => $event->booking_eventname . ' ' . $person->booking_price_descrip,
'invoice' => $invoiceid,
'no_shipping' => TRUE,
'no_note' => TRUE,
'currency_code' => 'AUD',
'return' => url('bookingfinal', array('absolute' => TRUE)),
'cancel_return' => url($path, array('absolute' => TRUE)),
'rm' => '2',
'amount' => $amount_owing,
'last_name' => $person->booking_lastname,
'first_name' => $person->booking_firstname,
'cmd' => '_xclick',
'notify_url' => url(BOOKING_PAYPAL_IPN_PATH, array('absolute' => TRUE)),
'business' => variable_get('booking_paypal_account', '')
);
$form['#action'] = url(variable_get('booking_paypal_sandbox', 0) ? BOOKING_PAYPAL_SUBMIT_URL_SANDBOX : BOOKING_PAYPAL_SUBMIT_URL, array('absolute' => TRUE));
//turn the array into a form
foreach($vars as $name => $value) {
$form[$name] = array(
'#type' => 'hidden',
'#value' => $value,
);
}
$form['submit'] = array(
'#type' => 'button',
'#value' => t($button_text),
);
//watchdog('booking', 'Booking Balance payment: @info', array ('@info' => var_export($form, TRUE)));
return $form;
}

View File

@@ -15,6 +15,7 @@ function booking_price_admin()
$header = array (
'booking_price_active' => t('Active'),
'booking_eventname' => t('Event Name'),
'booking_eventid' => t('Event ID'),
'booking_price_descrip' => t('Description'),
'booking_price' => t('Early-Bird Price'),
@@ -25,14 +26,17 @@ function booking_price_admin()
'booking_edit' => t('Edit Price'),
);
$result = db_query("SELECT pid, booking_eventid, booking_price, booking_late_price, booking_late_buttonid, booking_price_descrip, booking_buttonid, booking_price_active, " .
"booking_depositonly from {booking_price}");
$result = db_query("SELECT pid, p.booking_eventid, booking_price, booking_late_price, booking_late_buttonid, booking_price_descrip, " .
"booking_buttonid, booking_price_active, booking_depositonly, e.booking_eventname " .
"from {booking_price} p " .
"inner join {booking_event} e on e.eid = p.booking_eventid");
foreach($result as $data)
{
$options[$data->pid] = array
(
'booking_price_active' => $data->booking_price_active == 1 ? 'Yes' : 'No',
'booking_eventname' => $data->booking_eventname,
'booking_eventid' => $data->booking_eventid,
'booking_price_descrip' => $data->booking_price_descrip,
'booking_price' => $data->booking_price,
@@ -63,6 +67,12 @@ function booking_price_admin()
'#value' => t('Set Inactive'),
);
$form['submit_current'] = array
(
'#type' => 'submit',
'#value' => t('Change to current event'),
);
//watchdog('booking', 'Setting button form: @info', array ('@info' => var_export($form, TRUE)));
return array (
@@ -85,13 +95,24 @@ function booking_price_admin_submit($form, &$form_state) {
foreach($checkboxes as $key => $value) {
//only set the entries that are ticked
if ($value != 0)
{
if ($form_state['values']['op'] == 'Set Active')
if ($value != 0) {
//just update prices to match current event
if ($form_state['values']['op'] == 'Change to current event') {
db_update('booking_price')
->fields(array (
'booking_eventid' => $event->eid,
))
->condition('pid', $key)
->execute();
}
//either make a price active or inactive
else {
if ($form_state['values']['op'] == 'Set Active') {
$setting = 1;
else
}
else {
$setting = 0;
}
db_update('booking_price')
->fields(array (
'booking_eventid' => $event->eid,
@@ -100,8 +121,10 @@ function booking_price_admin_submit($form, &$form_state) {
->condition('pid', $key)
->execute();
}
}
}
} //value not 0
} //foreach checkbox
} //end function
function booking_price_form($node, &$form_state, $create, $editid = 0)
{

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,140 @@
function booking_node_presave($node) {
global $event;
if($node->type == 'booking')
{
$node->title = t('!event registration: !name',
array('!event' => $event->booking_eventname, '!name' => $node->booking_firstname . ' ' . $node->booking_lastname));
//watchdog('booking', 'Presave of person: @info', array('@info' => var_export($node, TRUE)));
if($node->type == 'booking') {
$title = t('!event registration: !name', array(
'!event' => $event->booking_eventname,
// no longer needed since applied at node creation
'!name' => _booking_ucname($node->booking_firstname . ' ' . $node->booking_lastname),
//'!name' => $node->booking_firstname . ' ' . $node->booking_lastname,
));
//strip any emojis from user input if that feature is enabled
if (variable_get('booking_enable_emoji_removal', 1) == 1) {
$title = _booking_remove_emoji($title);
}
$node->title = $title;
}
}
/**
* Function to create a mysql view of all information relating to an attendee
*
* @param
* @return
*/
function _booking_node_create_mysqlview()
{
global $event;
$studygroups = array();
//sometimes we will execute when hook_init hasn't been called
//for example at install or upgrade time
//so query the database directly for the event currently active
if ($event == NULL) {
watchdog('booking_debug', "Calling _booking_node_create_mysqlview() when hook_init not yet run.");
$event = db_query("SELECT * from {booking_event} where booking_event_active=1")->fetchObject();
}
$query = db_select('booking_person', 'p');
//add price info
$query->join('booking_price', 'pr', 'p.booking_payment_id = pr.pid');
//add the join for earlyaccess code if enabled
if (variable_get('booking_enable_earlyaccess_codes', 0) == 1) {
$query->leftJoin('booking_earlyaccess_codes', 'c', 'p.nid = c.booking_earlyaccess_code_nid');
}
//add travel form info if it exists
$query->leftJoin('booking_travel', 't', 'p.nid = t.booking_person_nid');
//add the joins for room allocation info if enabled
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$query->leftJoin('booking_room_mapping', 'rm', 'p.nid = rm.booking_nodeid');
$query->leftJoin('booking_room_definition', 'r', 'rm.booking_roomid = r.rid');
$query->leftJoin('booking_room_locations', 'l', 'l.lid = r.booking_room_location_id');
}
//add the joins to flatten out study groups into columns
if (variable_get('booking_enable_studygroups', 0) == 1) {
//get details of the study groups defined for this event
//but when this function gets called we don't have the global $event variable populated, so do the join here ourselves
$studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} l INNER JOIN {booking_event} e ON l.booking_eventid = e.eid WHERE e.booking_event_active=1");
$studygroups = $studygroups_query->fetchAllAssoc('sid');
foreach ($studygroups as $studygroup) {
$id = $studygroup->sid;
$query->leftJoin('booking_studygroup_mapping', 's' . $id, 'p.nid = s' . $id . '.booking_node_id and s' . $id . '.booking_studygroup_id = ' . $id);
}
}
//add the joins for variety session info if enabled
if (variable_get('booking_enable_variety_sessions', 0) == 1) {
$query->leftJoin('booking_variety_regn', 'v', 'p.nid = v.booking_person_nid');
}
//filter the results either by current active event
// @todo is this filter really necessary?
$query->condition('p.booking_eventid', $event->eid, '=');
//add the database fields we always want to retrieve
$query->fields('p')
->fields('t')
->fields('pr', array('booking_price', 'booking_price_descrip','booking_late_price'));
if (variable_get('booking_enable_earlyaccess_codes', 0) == 1) {
$query->fields('c', array('cid', 'booking_earlyaccess_code'));
}
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$query->fields('rm', array('booking_room_bedtype'))
->fields('r', array('rid', 'booking_room_location_id', 'booking_room_number'))
->fields('l');
}
//now add the study group fields if applicable
if (variable_get('booking_enable_studygroups', 0) == 1) {
foreach ($studygroups as $studygroup)
{
$id = $studygroup->sid;
$query->addField('s' . $id, 'booking_session_id', 'session' . $id);
$query->addField('s' . $id, 'booking_studygroup_role', 'session' . $id . '_role');
}
}
//add field for variety session registrations if enabled
if (variable_get('booking_enable_variety_sessions', 0) == 1) {
$query->fields('v', array('booking_variety_ids'));
}
//now that we have built the query as a SelectObject, turn it into a string we can use to create a view
$querystring=$query->__toString();
$querystring=str_replace("{",'',$querystring);
$querystring=str_replace("}",'',$querystring);
foreach($query->getArguments() as $key=> $item) {
if(!$item) {
$item = 'NULL';
}
$querystring=str_replace($key.')',$item.')',$querystring);
}
$querystring = "CREATE OR REPLACE VIEW booking_person_view AS " . $querystring;
watchdog('booking_debug', "<pre>Booking Person View creation query string:\n@info</pre>", array('@info' => print_r($querystring, true)));
$viewquery = db_query($querystring)->execute();
//$result = $viewquery->fetchObject();
watchdog('booking_debug', "<pre>Booking Person View creation result:\n@info</pre>", array('@info' => print_r($viewquery, true)));
}
/**
* Function to add single quote marks around a string
* @see booking_load_query
*
* @param $input - string to add quote marks around
* @return quoted string
*/
function _booking_quote_string($input) {
return sprintf("'%s'", $input);
}
/**
@@ -20,7 +148,29 @@ function booking_node_presave($node) {
*/
function booking_load_query($node_ids = NULL, $fetchAssoc = FALSE)
{
global $event;
//filter the results either by specific nodes if passed as a parameter or by all nodes matching the event id
if (! is_null($node_ids)) {
$nid_string = implode(',', array_map('_booking_quote_string', $node_ids));
$query_string = "SELECT * FROM {booking_person_view} WHERE nid IN ( " . $nid_string . " )";
//watchdog('booking_debug', "<pre>Loading node query:\n@info</pre>", array('@info' => print_r($query_string, true)));
$result = db_query($query_string)->fetchAllAssoc('nid');
}
else {
$result = db_query("SELECT * FROM {booking_person_view}")->fetchAllAssoc('nid');
}
//watchdog('booking', "<pre>Loading node query output:\n@info</pre>", array('@info' => print_r( $result, true)));
return $result;
}
/**
* Function to query the database for the complete object representing a registration
*
* @param $node_ids - a list of node IDs to query for
* @return list of objects
*/
function booking_load_query_old($node_ids = NULL, $fetchAssoc = FALSE)
{
//$studygroup_count = variable_get('booking_studygroup_count','0');
$studygroups = array();
@@ -108,6 +258,7 @@ function booking_load_query($node_ids = NULL, $fetchAssoc = FALSE)
}
*/
}
watchdog('booking_debug', "<pre>Loading node query:\n@info</pre>", array('@info' => print_r( (string)$query, true)));
//get the query result as either an associative array
if ($fetchAssoc == TRUE)
@@ -123,6 +274,13 @@ function booking_load_query($node_ids = NULL, $fetchAssoc = FALSE)
return $result;
}
/**
* Function implementing hook_load for the node-type booking
* @see booking_load_query
*
* @param $nodes - An array of the nodes being loaded, keyed by nid
* @return nothing
*/
function booking_load($nodes) {
global $event;
@@ -144,10 +302,21 @@ function booking_load($nodes) {
}
function booking_insert($node) {
watchdog('booking', 'Inserting node: @info', array('@info' => var_export($node, TRUE)));
//TODO: Generalise this by using the keys from $node instead of hard coding everything
$data = array();
foreach ($node as $key => $value) {
//check if the key is a field that belongs in the database
if ((strpos($key, "booking_") === 0) || $key === "nid") {
$data[$key] = $value;
}
}
watchdog('booking_debug', "<pre>Inserting node:\n@info</pre>", array('@info' => print_r($data, TRUE)));
db_insert('booking_person')->fields($data)->execute();
/*
db_insert('booking_person')
->fields(array(
'nid' => $node->nid,
@@ -157,27 +326,6 @@ function booking_insert($node) {
'booking_dob' => $node->booking_dob,
'booking_barcode' => $node->booking_barcode,
'booking_luckynum' => $node->booking_luckynum,
'booking_passport_num' => $node->booking_passport_num,
'booking_passport_issue_location' => $node->booking_passport_issue_location,
'booking_passport_issue_name' => $node->booking_passport_issue_name,
'booking_passport_expiry_date' => $node->booking_passport_expiry_date,
'booking_destination_country' => $node->booking_destination_country,
'booking_travel_insurance' => $node->booking_travel_insurance,
'booking_outflight_bookingnum' => $node->booking_outflight_bookingnum,
'booking_outflight_flightnum' => $node->booking_outflight_flightnum,
'booking_outflight_bookingnum' => $node->booking_outflight_bookingnum,
'booking_outflight_origin' => $node->booking_outflight_origin,
'booking_outflight_origin_ts' => $node->booking_outflight_origin_ts,
'booking_outflight_connecting_flightnum' => $node->booking_outflight_connecting_flightnum,
'booking_outflight_destination' => $node->booking_outflight_destination,
'booking_outflight_destination_ts' => $node->booking_outflight_destination_ts,
'booking_rtrnflight_bookingnum' => $node->booking_rtrnflight_bookingnum,
'booking_rtrnflight_flightnum' => $node->booking_rtrnflight_flightnum,
'booking_rtrnflight_origin' => $node->booking_rtrnflight_origin,
'booking_rtrnflight_origin_ts' => $node->booking_rtrnflight_origin_ts,
'booking_rtrnflight_connecting_flightnum' => $node->booking_rtrnflight_connecting_flightnum,
'booking_rtrnflight_destination' => $node->booking_rtrnflight_destination,
'booking_rtrnflight_destination_ts' => $node->booking_rtrnflight_destination_ts,
'booking_gender' => $node->booking_gender,
'booking_street' => $node->booking_street,
'booking_suburb' => $node->booking_suburb,
@@ -212,6 +360,7 @@ function booking_insert($node) {
'booking_total_pay_reqd' => $node->booking_total_pay_reqd,
'booking_guardian_name' => $node->booking_guardian_name,
'booking_guardian_type' => $node->booking_guardian_type,
'booking_guardian_email' => $node->booking_guardian_email,
'booking_guardian_phone' => $node->booking_guardian_phone,
'booking_guardian_phone_alt' => $node->booking_guardian_phone_alt,
'booking_medicare' => empty($node->booking_medicare) ? '' : $node->booking_medicare,
@@ -240,6 +389,7 @@ function booking_insert($node) {
'booking_comment_field' => $node->booking_comment_field,
))
->execute();
*/
}
/**
@@ -250,12 +400,77 @@ function booking_insert($node) {
*/
function booking_update($node) {
global $event;
$data = array();
//TODO: make sure these exclusions match with admin selected options (eg passport details)
//these fields should be stored in the database as Y or N, but come back from the FAPI as 1 or 0
$boolean_keys = array('booking_baptised', 'booking_married', 'booking_help_praying', 'booking_help_meditations', 'booking_help_reading',
'booking_help_chairing', 'booking_help_readgroup_lead', 'booking_help_discussgroup_lead', 'booking_lifesaver',
'booking_firstaid', 'booking_nurse', 'booking_doctor', 'booking_has_mission_experience', 'booking_skills_builder',
'booking_skills_cooking', 'booking_skills_childminding', 'booking_skills_language', 'booking_skills_other',
'booking_welfare_required', 'booking_payment_complete', 'booking_refund_processed', 'booking_committee_member'
);
//these fields should be zero if not defined
$default_zero_keys = array('booking_luckynum', 'booking_bf_gf_nid', 'booking_keepseparate_id', 'booking_refund_due', 'booking_earlyaccess_code_id',
'booking_prev_sw_count');
//some fields are present in $node from the SQL view we use that don't belong in booking_person so exclude them
$excluded_keys = array('booking_person_nid', 'booking_transport_type', 'booking_transport_from_morriset_reqd', 'booking_transport_to_morriset_reqd',
'booking_flightnum_inbound', 'booking_flight_datetime_inbound', 'booking_flightnum_outbound', 'booking_flight_datetime_outbound', 'booking_accom_before_reqd',
'booking_accom_before_staying_with', 'booking_accom_after_reqd', 'booking_accom_after_staying_with', 'booking_roomlocation_descrip',
'booking_roomlocation_active', 'booking_price', 'booking_price_descrip', 'booking_late_price', 'booking_earlyaccess_code',
'booking_room_bedtype', 'booking_room_location_id', 'booking_room_number', 'booking_agreement', 'booking_deposit_timestamp', 'booking_variety_ids'
);
//before we update this user, check what their previous registration status was
$previous_status = db_query("SELECT booking_status, booking_payment_id, booking_total_pay_reqd, booking_amount_paid FROM {booking_person} where nid = :nid", array(
':nid' => $node->nid))
->fetchObject();
// process the input data before updating database
foreach ($node as $key => $value) {
//check if the key is a field that belongs in the database
if ((strpos($key, "booking_") === 0) || $key === "nid") {
//what special handling does this field need?
//handle dates properly
if ((strpos($key, "booking_dob") === 0) || (strpos($key, "booking_passport_issue_date") === 0)) {
$data[$key] = _date_to_ts($value);
}
//skip these fields from the update of booking_person
elseif (in_array($key, $excluded_keys, FALSE)) {
//do nothing
}
//this field needs 0/1 translated to N/Y
elseif (in_array($key, $boolean_keys, FALSE)) {
$data[$key] = $value == 1 ? 'Y' : 'N';
}
//this field has a default value of zero rather than null
elseif (in_array($key, $default_zero_keys, FALSE)) {
$data[$key] = $value == '' ? 0 : $value;
}
//just handle this field normally
else {
if (variable_get('booking_enable_emoji_removal', 1) == 1) {
$data[$key] = _booking_remove_emoji($value);
}
else {
$data[$key] = $value;
}
}
}
}
//make sure the name is the correct case
//not really needed for node updates since it now applies at node creation
$data['booking_firstname'] = _booking_ucname($data['booking_firstname']);
$data['booking_lastname'] = _booking_ucname($data['booking_lastname']);
//watchdog('booking_debug', "<pre>Old node:\n@info</pre>", array('@info' => var_export($node, TRUE)));
watchdog('booking_debug', "<pre>Updating node:\n@info</pre>", array('@info' => var_export($data, TRUE)));
db_update('booking_person')->fields($data)->condition('nid', $node->nid)->execute();
/*
//watchdog('booking', 'Updating node: @info', array('@info' => var_export($node, TRUE)));
db_update('booking_person')
->fields(array (
@@ -264,27 +479,6 @@ function booking_update($node) {
'booking_dob' => _date_to_ts($node->booking_dob),
'booking_barcode' => $node->booking_barcode,
'booking_luckynum' => $node->booking_luckynum == '' ? 0 : $node->booking_luckynum,
'booking_passport_num' => $node->booking_passport_num,
'booking_passport_issue_location' => $node->booking_passport_issue_location,
'booking_passport_issue_name' => $node->booking_passport_issue_name,
'booking_passport_expiry_date' => _date_to_ts($node->booking_passport_expiry_date),
'booking_destination_country' => $node->booking_destination_country,
'booking_travel_insurance' => $node->booking_travel_insurance,
'booking_outflight_bookingnum' => $node->booking_outflight_bookingnum,
'booking_outflight_flightnum' => $node->booking_outflight_flightnum,
'booking_outflight_bookingnum' => $node->booking_outflight_bookingnum,
'booking_outflight_origin' => $node->booking_outflight_origin,
'booking_outflight_origin_ts' => _datetime_to_ts($node->booking_outflight_origin_ts),
'booking_outflight_connecting_flightnum' => $node->booking_outflight_connecting_flightnum,
'booking_outflight_destination' => $node->booking_outflight_destination,
'booking_outflight_destination_ts' => _datetime_to_ts($node->booking_outflight_destination_ts),
'booking_rtrnflight_bookingnum' => $node->booking_rtrnflight_bookingnum,
'booking_rtrnflight_flightnum' => $node->booking_rtrnflight_flightnum,
'booking_rtrnflight_origin' => $node->booking_rtrnflight_origin,
'booking_rtrnflight_origin_ts' => _datetime_to_ts($node->booking_rtrnflight_origin_ts),
'booking_rtrnflight_connecting_flightnum' => $node->booking_rtrnflight_connecting_flightnum,
'booking_rtrnflight_destination' => $node->booking_rtrnflight_destination,
'booking_rtrnflight_destination_ts' => _datetime_to_ts($node->booking_rtrnflight_destination_ts),
'booking_gender' => $node->booking_gender,
'booking_street' => $node->booking_street,
'booking_suburb' => $node->booking_suburb,
@@ -302,6 +496,7 @@ function booking_update($node) {
'booking_partner_id' => $node->booking_partner_id,
'booking_dependant_children' => $node->booking_dependant_children,
'booking_bf_gf_nid' => $node->booking_bf_gf_nid == '' ? 0 : $node->booking_bf_gf_nid,
'booking_keepseparate_id' => $node->booking_keepseparate_id == '' ? 0 : $node->booking_keepseparate_id,
'booking_room_mate1' => $node->booking_room_mate1,
'booking_room_mate2' => $node->booking_room_mate2,
'booking_random_facts' => $node->booking_random_facts,
@@ -321,6 +516,7 @@ function booking_update($node) {
'booking_refund_due' => $node->booking_refund_due == '' ? 0 : $node->booking_refund_due,
'booking_guardian_name' => $node->booking_guardian_name,
'booking_guardian_type' => $node->booking_guardian_type,
'booking_guardian_email' => $node->booking_guardian_email,
'booking_guardian_phone' => $node->booking_guardian_phone,
'booking_guardian_phone_alt' => $node->booking_guardian_phone_alt,
'booking_medicare' => $node->booking_medicare,
@@ -346,20 +542,20 @@ function booking_update($node) {
'booking_random_facts' => $node->booking_random_facts,
'booking_status' => $node->booking_status,
'booking_comment_field' => $node->booking_comment_field,
'booking_song_choice' => $node->booking_song_choice,
'booking_freestyle_text' => $node->booking_freestyle_text,
))
->condition('nid', $node->nid)
->execute();
*/
//***now process some post-update triggers***
//if booking_partner_id is set, make sure the nid it refers to has this node as its booking_partner_id
if ($node->booking_partner_id != 0)
{
if ($node->booking_partner_id != 0) {
$partner = db_query("Select booking_partner_id from {booking_person} where nid = :nid",
array(':nid' => $node->booking_partner_id))
->fetchObject();
if ($partner->booking_partner_id == 0)
{
if ($partner->booking_partner_id == 0) {
watchdog('booking', 'Updating partner node !partner to refer to this node !nid',
array('!partner' => $node->booking_partner_id, '!nid' => $node->nid));
//update the partner id of the partner to refer to this node
@@ -372,6 +568,24 @@ function booking_update($node) {
}
}
//repeat the process for bf/gf
if ($node->booking_bf_gf_nid != 0) {
$partner = db_query("Select booking_bf_gf_nid from {booking_person} where nid = :nid",
array(':nid' => $node->booking_bf_gf_nid))
->fetchObject();
if ($partner->booking_bf_gf_nid == 0) {
watchdog('booking', 'Updating bf/gf node !partner to refer to this node !nid',
array('!partner' => $node->booking_bf_gf_nid, '!nid' => $node->nid));
//update the partner id of the partner to refer to this node
db_update('booking_person')
->fields(array(
'booking_bf_gf_nid' => $node->nid,
))
->condition('nid', $node->booking_bf_gf_nid)
->execute();
}
}
//status change triggers start here
//check if someone has moved to not-coming list from the booked-in list
@@ -394,27 +608,28 @@ function booking_update($node) {
_booking_person_rooms_cleanup($node->nid);
//check if there is room on the booked-in list
if (_booking_check_bookings_full() == False)
{
if (_booking_check_bookings_full() == False) {
watchdog('booking', 'Looks like there was room on the booked in list, so lets tell the next person');
//find the first person on the waiting list
$temp_nid = _booking_get_waitinglist_top();
if ($temp_nid != -1) //-1 means there was no one on the waiting list
{
//-1 means there was no one on the waiting list
if ($temp_nid != -1) {
//update their registration status
_booking_change_status($temp_nid,1);
//send them an email
_booking_promoted_from_waitinglist_email($temp_nid);
}
}
else
else {
watchdog('booking', 'Still no room on the booked in list though.');
}
// Update waiting list positions
_booking_waitinglist_update_trigger();
}
//check if someone has moved to booked-in list from waiting-list
elseif ($previous_status->booking_status == 2 && $node->booking_status == 1)
{
elseif ($previous_status->booking_status == 2 && $node->booking_status == 1) {
watchdog('booking', 'Detected person moving from Waiting list to Booked In');
//send them an email
@@ -437,10 +652,11 @@ function booking_update($node) {
$waitinglist_nid = _booking_get_waitinglist_top();
}
// Update waiting list positions
_booking_waitinglist_update_trigger();
}
//check if someone has been demoted to the "missed payment deadline" status from being booked-in
elseif ($previous_status->booking_status == 1 && $node->booking_status == 4)
{
elseif ($previous_status->booking_status == 1 && $node->booking_status == 4) {
watchdog('booking', 'Detected person moving from Booked In list to Missed Payment Deadline list.');
//let this person know they're no longer "booked in"
@@ -453,29 +669,25 @@ function booking_update($node) {
_booking_person_rooms_cleanup($node->nid);
//check if there is room on the booked-in list
if (_booking_check_bookings_full() == False)
{
if (_booking_check_bookings_full() == False) {
watchdog('booking', 'Position available, so lets tell the next person');
//find the first person on the waiting list
$temp_nid = _booking_get_waitinglist_top();
if ($temp_nid != -1) //-1 means there was no one on the waiting list
{
//-1 means there was no one on the waiting list
if ($temp_nid != -1) {
//update their registration status
_booking_change_status($temp_nid, 1);
//send them an email
_booking_promoted_from_waitinglist_email($temp_nid);
}
}
else
{
else {
watchdog('booking', 'Still no room on the booked in list.');
}
}
//if someone is moving to the not-coming list from the waiting list
elseif ($previous_status->booking_status == 2 && $node->booking_status == 3)
{
elseif ($previous_status->booking_status == 2 && $node->booking_status == 3) {
watchdog('booking', 'Detected person moving from waiting list to No Longer Coming');
//let this person know their request has been processed
_booking_demoted_to_notcoming_email($node->nid);
@@ -490,8 +702,7 @@ function booking_update($node) {
}
//if we're not automatically sending emails on registration
//and someone moved from not-paid to booked-in (ie, manual payment process)
elseif (variable_get('booking_auto_confirm_email', 0) == 0 && $previous_status->booking_status == 0 && $node->booking_status == 1)
{
elseif (variable_get('booking_auto_confirm_email', 0) == 0 && $previous_status->booking_status == 0 && $node->booking_status == 1) {
watchdog('booking', 'Detected person moving from Not Paid list to Booked In list');
//make sure the booked in list isn't full
@@ -504,11 +715,9 @@ function booking_update($node) {
}
}
//if someone moved from the not-paid list to waiting list by manual update
elseif ($previous_status->booking_status == 0 && $node->booking_status == 2)
{
elseif ($previous_status->booking_status == 0 && $node->booking_status == 2) {
watchdog('booking', 'Detected person moving from Not Paid list to Waiting List');
//create a manual payment entry of zero dollars
//so things like the waiting list report work
$result = db_insert('booking_payment')
@@ -537,8 +746,7 @@ function booking_update($node) {
}
//if the payment ID has changed then update the total pay required
if ($previous_status->booking_payment_id != $node->booking_payment_id)
{
if ($previous_status->booking_payment_id != $node->booking_payment_id) {
$total_due = 0;
watchdog('booking', 'Detected payment type change for attendee');
@@ -592,44 +800,64 @@ function booking_delete($node) {
}
/**
* Helper function to update the waiting list position for everyone on the waiting list
*/
function _booking_waitinglist_update_trigger()
{
global $event;
$waiting_list = _booking_get_waitinglist();
$counter = 1;
foreach ($waiting_list as $person) {
//watchdog('booking_debug', "Updating node !nid to have waitlist position of !counter", array('!nid' => $person->nid, '!counter' => $counter));
db_update('booking_person')
->fields(array(
'booking_waitlist_pos' => $counter++,
))
->condition('nid', $person->nid)
->execute();
}
}
function booking_view($node, $view_mode) {
global $event;
$rows = array();
$travel_rows = array();
//watchdog('booking_debug', 'booking view node: <pre>@info</pre>', array('@info' => print_r( $node, true)));
//calculate the price owed by this person
//if (_booking_is_earlybird() == true || _booking_amount_owing($node->nid) == 0)
if (_booking_is_earlybird() == true || _booking_amount_owing($node) == 0 || $node->booking_committee_member == 'Y' || $node->booking_welfare_required == 'Y')
{
if (_booking_is_earlybird() == true || _booking_amount_owing($node) == 0 || $node->booking_committee_member == 'Y' || $node->booking_welfare_required == 'Y') {
$price = $node->booking_price;
}
else
else {
$price = $node->booking_late_price;
}
//include the price description to display with this view
$payment_type = $node->booking_price_descrip . ' ($' . $price . ')';
//look up the actual name for a linked partner
if ($node->booking_partner_id != 0)
{
if ($node->booking_partner_id != 0) {
$query = db_query("Select booking_firstname, booking_lastname from {booking_person} where nid = :nid",
array(':nid' => $node->booking_partner_id))
->fetchObject();
$partner_name = $query->booking_firstname . " " . $query->booking_lastname;
}
else
else {
$partner_name = "N/A";
}
//also look up the actual name if a boyfriend/girlfriend is defined
if ($node->booking_bf_gf_nid != 0)
{
if ($node->booking_bf_gf_nid != 0) {
$query = db_query("Select booking_firstname, booking_lastname from {booking_person} where nid = :nid",
array(':nid' => $node->booking_bf_gf_nid))
->fetchObject();
$bf_gf = $query->booking_firstname . " " . $query->booking_lastname;
}
else
else {
$bf_gf = "N/A";
}
//define column widths along with the header
$header = array(
@@ -642,69 +870,46 @@ function booking_view($node, $view_mode) {
$rows[] = array(t('Name:'), t('!first !last', array('!first' => $node->booking_firstname, '!last' => $node->booking_lastname)));
$rows[] = array(t('Gender:'), t('!gender', array('!gender' => $node->booking_gender == 'M' ? 'Male' : 'Female')));
$rows[] = array(t('Status:'), t('!status', array('!status' => _booking_status_generate($node->booking_status))));
if (variable_get('booking_enable_earlyaccess_codes', 0) == 1) {
$rows[] = array(t('Early Access Code:'), t('!code', array('!code' => $node->booking_earlyaccess_code)));
}
$rows[] = array(t('Internal comments on this registration:'), t('<i>!comment</i>', array('!comment' => $node->booking_comment_field)));
$rows[] = array(t('Committee Member:'), t('!ans', array('!ans' => ($node->booking_committee_member == 'Y' ? '<b>Yes</b>' : 'No'))));
$rows[] = array(t('Welfare Required:'), $node->booking_welfare_required == 'Y' ? 'Yes' : 'No');
$rows[] = array(t('Barcode:'), t('!id', array('!id' => $node->booking_barcode)));
$rows[] = array(t('QR Code:'), t('!id', array('!id' => $node->booking_qrcode_url)));
$rows[] = array(t('Lanyard lucky number:'), $node->booking_luckynum);
$rows[] = array(t('Reading Group:'), t('!group', array('!group' => $node->booking_readinggroup)));
$rows[] = array(t('Date of birth:'), t('!dob', array('!dob' => format_date($node->booking_dob, 'custom', 'd/m/Y'))));
$rows[] = array(t('Email address:'), t('!email', array('!email' => $node->booking_email)));
if (variable_get('booking_enable_passport', 1) == 1)
{
$rows[] = array(t('Passport Number:'), $node->booking_passport_num);
$rows[] = array(t('Passport Expiry:'), t('!timestamp', array('!timestamp' => _booking_convert_ts($node->booking_passport_expiry_date)->format('d/m/Y'))));
$rows[] = array(t('Passport Exact Issued Name:'), $node->booking_passport_issue_name);
$rows[] = array(t('Passport Issue Location:'), $node->booking_passport_issue_location);
$rows[] = array(t('Destination Country:'), $node->booking_destination_country);
$rows[] = array(t('Travel Insurance details:'), $node->booking_travel_insurance);
//outbound flight
$flight_rows[] = array(t('Internal Flight Booking Reference:'), $node->booking_outflight_bookingnum);
$flight_rows[] = array(t('Internal Flight Number:'), $node->booking_outflight_flightnum);
$flight_rows[] = array(t('Internal Flight Origin to Destination:'), $node->booking_outflight_origin);
$flight_rows[] = array(t('Internal Flight Departure Time:'),
$node->booking_outflight_origin_ts == 0 ? '' : format_date($node->booking_outflight_origin_ts, 'custom', 'd/m/Y H:i') );
$flight_rows[] = array(t('Connecting Flight Number:'), $node->booking_outflight_connecting_flightnum);
$flight_rows[] = array(t('Connecting Flight Origin to Destination:'), $node->booking_outflight_destination);
$flight_rows[] = array(t('Internal Flight Arrival Time:'),
$node->booking_outflight_destination_ts == 0 ? '' : format_date($node->booking_outflight_destination_ts, 'custom', 'd/m/Y H:i') );
//return flight
$flight_rows[] = array(t('Return Internal Flight Booking Reference:'), $node->booking_rtrnflight_bookingnum);
$flight_rows[] = array(t('Return Internal Flight Number:'), $node->booking_rtrnflight_flightnum);
$flight_rows[] = array(t('Return Internal Flight Origin to Destination:'), $node->booking_rtrnflight_origin);
$flight_rows[] = array(t('Return Internal Flight Departure Time:'),
$node->booking_rtrnflight_origin_ts == 0 ? '' : format_date($node->booking_rtrnflight_origin_ts, 'custom', 'd/m/Y H:i') );
$flight_rows[] = array(t('Connecting Flight Number:'), $node->booking_rtrnflight_connecting_flightnum);
$flight_rows[] = array(t('Connecting Flight Origin to Destination:'), $node->booking_rtrnflight_destination);
$flight_rows[] = array(t('Return Internal Flight Arrival Time:'),
$node->booking_rtrnflight_destination_ts == 0 ? '' : format_date($node->booking_rtrnflight_destination_ts, 'custom', 'd/m/Y H:i') );
//add the flight info to a new section
$flight_heading = t("<h2>Internal Flight Details</h2>");
$node->content['flight-heading'] = array(
'#markup' => $flight_heading,
'#weight' => 2,
);
$node->content['flight-details'] = array(
'#markup' => theme('table', array('header' => $header, 'rows' => $flight_rows)),
'#weight' => 3,
);
}
$rows[] = array(t('Payment Type Selected:'), t('!amount_paid', array('!amount_paid' => $payment_type)));
$rows[] = array(t('Amount Paid:'), t('!amount_paid', array('!amount_paid' => $node->booking_amount_paid)));
$rows[] = array(t('Payment Complete Flag:'), t('!ans', array('!ans' => $node->booking_payment_complete == 'Y' ? 'Yes' : 'No')));
$rows[] = array(t('Total Amount Due:'), t('!amount_paid', array('!amount_paid' => $node->booking_total_pay_reqd)));
$rows[] = array(t('Refund Due:'), t('!amount_due', array('!amount_due' => $node->booking_refund_due)));
$rows[] = array(t('Refund Processed:'), t('!ans', array('!ans' => ($node->booking_refund_processed == 'Y' ? 'Yes' : 'No'))));
$rows[] = array(t('Reading Group:'), t('!group', array('!group' => $node->booking_readinggroup)));
$rows[] = array(t('Random Facts:'), t('!facts', array('!facts' => $node->booking_random_facts)));
if (variable_get('booking_enable_tshirts', 0) == 1)
{
$rows[] = array(t('Hoodie Size:'), $node->booking_shirt_size);
//$rows[] = array(t('Random Facts:'), t('!facts', array('!facts' => $node->booking_random_facts)));
if (variable_get('booking_enable_songchoice', 0) == 1) {
$rows[] = array(t('Song Choice:'), t('!song', array('!song' => $node->booking_song_choice)));
}
if (variable_get('booking_enable_freestyle', 0) == 1) {
$rows[] = array(t('Freestyle:'), t('!song', array('!song' => $node->booking_freestyle_text)));
}
if (variable_get('booking_enable_previous_studyweeks', 0) == 1) {
$rows[] = array(t('Number of previous SW:'), t('!sw', array('!sw' => $node->booking_prev_sw_count)));
}
if (variable_get('booking_enable_tshirts', 0) == 1) {
$rows[] = array(t('Hoodie Size:'), t('!size', array('!size' => $node->booking_shirt_size)));
}
$rows[] = array(t('Ecclesia:'), t('!ecclesia', array('!ecclesia' => $node->booking_ecclesia)));
$rows[] = array(t('Baptised:'), t('!ans', array('!ans' => ($node->booking_baptised == 'Y' ? 'Yes' : 'No'))));
$rows[] = array(t('Married:'), t('!ans', array('!ans' => ($node->booking_married == 'Y' ? 'Yes' : 'No'))));
if (variable_get('booking_ask_dependant_children', 0) == 1) {
$rows[] = array(t('Bringing dependant children:'), t('!ans', array('!ans' => ($node->booking_dependant_children == 'Y' ? 'Yes' : 'No'))));
}
$rows[] = array(t('Linked Partner:'), t($partner_name));
$rows[] = array(t('Linked Boyfriend/Girlfriend:'), t($bf_gf));
$rows[] = array(t('Node ID to keep separate:'), $node->booking_keepseparate_id == 0 ? 'N/A' : $node->booking_keepseparate_id);
$rows[] = array(t('Home Phone Number:'), t('!home', array('!home' => $node->booking_phone)));
$rows[] = array(t('Mobile Phone Number:'), t('!mob', array('!mob' => $node->booking_mobile)));
$rows[] = array(t('Postal Address:'), t('!street<br />!suburb !state !code<br />!country',
@@ -712,34 +917,24 @@ function booking_view($node, $view_mode) {
'!state' => ($node->booking_state == 'N/A' ? '' : $node->booking_state),
'!code' => $node->booking_postcode,
'!country' => $node->booking_country)));
$rows[] = array(t('Ecclesia:'), t('!ecclesia', array('!ecclesia' => $node->booking_ecclesia)));
$rows[] = array(t('Baptised:'), t('!ans', array('!ans' => ($node->booking_baptised == 'Y' ? 'Yes' : 'No'))));
$rows[] = array(t('Married:'), t('!ans', array('!ans' => ($node->booking_married == 'Y' ? 'Yes' : 'No'))));
if (variable_get('booking_ask_dependant_children', 0) == 1)
{
$rows[] = array(t('Bringing dependant children:'), t('!ans', array('!ans' => ($node->booking_dependant_children == 'Y' ? 'Yes' : 'No'))));
}
$rows[] = array(t('Linked Partner:'), t($partner_name));
$rows[] = array(t('Linked Boyfriend/Girlfriend:'), t($bf_gf));
$rows[] = array(t('Emergency Contact Name:'), $node->booking_guardian_name);
$rows[] = array(t('Emergency Contact Relationship:'), $node->booking_guardian_type);
$rows[] = array(t('Emergency Contact Email Address:'), $node->booking_guardian_email);
$rows[] = array(t('Emergency Contact Phone:'), $node->booking_guardian_phone);
$rows[] = array(t('Emergency Contact Alternate Phone:'), $node->booking_guardian_phone_alt);
if (variable_get('booking_enable_medicare', 1) == 1)
$rows[] = array(t('Medicare Number:'), $node->booking_medicare);
if (variable_get('booking_enable_medicare', 1) == 1) {
$rows[] = array(t('Medicare Number:'), $node->booking_medicare);
}
$rows[] = array(t('Special Dietary Requirements:'), $node->booking_dietary);
$rows[] = array(t('Special Medical Conditions:'), $node->booking_medical_conditions);
if (variable_get('booking_enable_roommate', 0) == 1)
{
if (variable_get('booking_enable_roommate', 0) == 1) {
$rows[] = array(t('Preferred room-mates:'), t('!room', array('!room' => $node->booking_room_mate1 . ' ' . $node->booking_room_mate2)));
}
if (variable_get('booking_enable_helpareas', 1) == 1)
{
if (variable_get('booking_enable_helpareas', 1) == 1) {
$rows[] = array(t('Qualified Life Saver:'), $node->booking_lifesaver == 'Y' ? 'Yes' : 'No');
$rows[] = array(t('Qualified First Aider:'), $node->booking_firstaid == 'Y' ? 'Yes' : 'No');
$rows[] = array(t('Qualified Nurse:'), $node->booking_nurse == 'Y' ? 'Yes' : 'No');
@@ -763,8 +958,7 @@ function booking_view($node, $view_mode) {
$rows[] = array(t('Help areas:'), t('!help', array('!help' => $help_areas)));
}
if (variable_get('booking_enable_skills', 1) == 1)
{
if (variable_get('booking_enable_skills', 1) == 1) {
$skill_areas = '';
if ($node->booking_skills_builder == 'Y')
$skill_areas .= 'builder, ';
@@ -780,11 +974,9 @@ function booking_view($node, $view_mode) {
$rows[] = array(t('Previous Mission Experience:'), $node->booking_mission_experience_details);
}
$rows[] = array(t('Temporary UUID:'), $node->booking_tempid);
$rows[] = array(t('Lanyard lucky number:'), $node->booking_luckynum);
//display room allocation data if enabled
if (variable_get('booking_enable_roomallocations', 0) == 1)
{
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$room_heading = t("<h2>Room Allocation</h2><p>!link</p>",
array('!link' => l(t('Edit Room Allocation'), t('admin/booking/!id/edit-room', array('!id' => $node->nid)), array('query' => drupal_get_destination()) )
));
@@ -806,8 +998,7 @@ function booking_view($node, $view_mode) {
}
//add the travel info if it has been defined for this attendee
if (! empty($node->tid))
{
if (! empty($node->tid)) {
$travel_heading = t("<h2>Travel Details</h2><p>!link</p>",
array('!link' => l(t('Edit Travel Details'), t('node/!id/edit', array('!id' => $node->tid)))
));
@@ -849,8 +1040,7 @@ function booking_view($node, $view_mode) {
//watchdog('booking', "<pre>Displaying node studygroups query output:\n@info</pre>", array('@info' => print_r( $studygroups, true)));
foreach ($studygroups as $studygroup)
{
foreach ($studygroups as $studygroup) {
//calculate the session references
$sessionid = "session" . $studygroup->sid;
$roleid = $sessionid . "_role";
@@ -859,21 +1049,8 @@ function booking_view($node, $view_mode) {
$group_rows[] = array(t('Role'), _booking_studygroup_role_lookup($node->$roleid));
}
/*
for ($i = 1; $i <= variable_get('booking_studygroup_count','0'); $i++)
{
//calculate the session references
$sessionid = "session" . $i;
$roleid = $sessionid . "_role";
$group_rows[] = array(t('<b>' . $studygroups[$i]->booking_studygroup_descrip . '</b> group number'), $node->$sessionid);
$group_rows[] = array(t('Role'), _booking_studygroup_role_lookup($node->$roleid));
}
*/
//only add to the render array if there were some study groups found
if (count($group_rows) > 0)
{
if (count($group_rows) > 0) {
$node->content['group-heading'] = array(
'#markup' => $studygroup_heading,
'#weight' => 8,
@@ -884,7 +1061,6 @@ function booking_view($node, $view_mode) {
'#weight' => 9,
);
}
}
$node->content['details'] = array(

View File

@@ -38,12 +38,11 @@ function booking_report_summary() {
$header[] = array('data' => t('Name'), 'field' => 'booking_lastname');
$header[] = array('data' => t('Booking Status'), 'field' => 'booking_status');
if (variable_get('booking_enable_studygroups', 0) == 1)
{
// Add some optional columns
if (variable_get('booking_enable_studygroups', 0) == 1) {
$header[] = array('data' => t('Studygroups'));
}
if (variable_get('booking_enable_roomallocations', 0) == 1)
{
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$header[] = array('data' => t('Room'));
}
@@ -79,7 +78,7 @@ function booking_report_summary() {
$query->orderBy('state_count', 'DESC');
$state_stats = $query->execute();
//TODO: add some info to a hash so we can calculate age info and generate the actual rows after the more detailed summary loop
//add some age info to an array so we can calculate age info and generate the actual rows after the more detailed summary loop
//include count of guys, girls, minimum, maximum and average ages
foreach ($state_stats as $state) {
if (strcmp($state->booking_country,'Australia') == 0 ) {
@@ -141,19 +140,16 @@ function booking_report_summary() {
$table_sort = $query->extend('TableSort')->orderbyHeader($header);
$result = $table_sort->execute();
foreach ($result as $person)
{
foreach ($result as $person) {
$this_row = array();
//$amount_owing = _booking_amount_owing($person->nid, 0, FALSE);
$amount_owing = _booking_amount_owing($person, 0, FALSE);
//calculate the travel link
if ($person->tid > 0)
{
if ($person->tid > 0) {
$travel_link = l(t('Travel'), t('node/!id/edit', array('!id' => $person->tid)));
}
else
{
else {
$travel_link = t('N/A');
}
@@ -164,12 +160,10 @@ function booking_report_summary() {
);
$this_row[] = _booking_status_generate($person->booking_status);
if (variable_get('booking_enable_studygroups', 0) == 1)
{
if (variable_get('booking_enable_studygroups', 0) == 1) {
$this_row[] = l(t('Groups'), t('admin/booking/!id/edit-studygroup-membership', array('!id' => $person->nid)));
}
if (variable_get('booking_enable_roomallocations', 0) == 1)
{
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$this_row[] =l(t('Room'), t('admin/booking/!id/edit-room', array('!id' => $person->nid)));
}
@@ -189,39 +183,44 @@ function booking_report_summary() {
$total_paid += $person->booking_amount_paid;
//subtract any refund
if ($person->booking_refund_processed == 'Y' && $person->booking_refund_due > 0)
{
if ($person->booking_refund_processed == 'Y' && $person->booking_refund_due > 0) {
$total_refunds += $person->booking_refund_due;
}
//travel form completed?
if (! empty($person->tid))
if (! empty($person->tid)) {
$travelform_count++;
}
//booking status
if ($person->booking_status == 0)
if ($person->booking_status == 0) {
$notpaid_counter++;
elseif ($person->booking_status == 1)
}
elseif ($person->booking_status == 1) {
$bookedin_counter++;
elseif ($person->booking_status == 2)
}
elseif ($person->booking_status == 2) {
$waiting_counter++;
elseif ($person->booking_status == 5)
}
elseif ($person->booking_status == 5) {
$hosts_counter++;
else
}
else {
$notcoming_counter++;
}
//welfare
if ($person->booking_welfare_required == 'Y')
if ($person->booking_welfare_required == 'Y') {
$welfare_count++;
}
//committee?
if ($person->booking_committee_member == 'Y')
if ($person->booking_committee_member == 'Y') {
$committee_count++;
}
//fully paid?
if ($amount_owing == 0)
if ($amount_owing == 0) {
$fullypaid_count++;
}
$person_count++;
$state = strcmp($person->booking_country,'Australia') == 0 ? $person->booking_state : 'International';
@@ -232,13 +231,13 @@ function booking_report_summary() {
$dob_total += $person->booking_dob;
//store data for average ages per gender and state
if ($person->booking_gender == 'M')
{
if ($person->booking_gender == 'M') {
$male_count++;
$male_dob_total += $person->booking_dob;
$state_statistics[$state]->male_avg += $person->booking_dob;
$state_statistics[$state]->male_count++;
} else {
}
else {
$female_count++;
$female_dob_total += $person->booking_dob;
$state_statistics[$state]->female_avg += $person->booking_dob;
@@ -279,7 +278,8 @@ function booking_report_summary() {
));
$output .= t("<h3>Ages</h3>");
$output .= t("<p>The combined average age at the start of the week will be !average.<br />The male average age will be !maleaverage.<br />The female average age will be !femaleaverage.</p>",
array('!average' => _booking_avg_age($dob_total, $male_count + $female_count, $event->booking_event_start), '!maleaverage' => _booking_avg_age($male_dob_total, $male_count, $event->booking_event_start),
array('!average' => _booking_avg_age($dob_total, $male_count + $female_count, $event->booking_event_start),
'!maleaverage' => _booking_avg_age($male_dob_total, $male_count, $event->booking_event_start),
'!femaleaverage' => _booking_avg_age($female_dob_total, $female_count, $event->booking_event_start)
));
$output .= t("<h3>Finances</h3>");
@@ -427,6 +427,107 @@ function booking_report_flight_details() {
return $result;
}
/**
* List everyone's travel info
*/
function booking_report_travel() {
global $event;
//$form = array();
$prefix = t("<h2>Travel Details</h2>");
//define sorting information with the header
//as per http://www.drup-all.com/blog/table-sort-pagination-drupal-7
$header = array();
$header[] = array('data' => t('Name'), 'field' => 'booking_lastname');
//$header[] = array('data' => t('Edit'), 'field' => 'nid', 'sort' => 'asc');
$header[] = array('data' => t('State'), 'field' => 'booking_state');
$header[] = array('data' => t('Transport Type'), 'field' => 'booking_transport_type');
$header[] = array('data' => t('Catching train from airport?'), 'field' => 'booking_transport_from_morriset_reqd');
$header[] = array('data' => t('Inbound Flight'), 'field' => 'booking_flightnum_inbound');
$header[] = array('data' => t('Inbound Time'), 'field' => 'booking_flight_datetime_inbound');
$header[] = array('data' => t('Outbound Flight'), 'field' => 'booking_flightnum_outbound');
$header[] = array('data' => t('Outbound Time'), 'field' => 'booking_flight_datetime_outbound');
$header[] = array('data' => t('Accommodation Before?'), 'field' => 'booking_accom_before_reqd');
$header[] = array('data' => t('Accommodation After?'), 'field' => 'booking_accom_after_reqd');
//get travel info from database
$query = db_select('booking_person', 'p');
$query->leftJoin('booking_travel', 't', 'p.nid = t.booking_person_nid');
//include people either booked in or on the waiting list or hosts, that belong to the current event id
$db_or = db_or();
$db_or->condition('p.booking_status', 1, '=');
$db_or->condition('p.booking_status', 2, '=');
$db_or->condition('p.booking_status', 5, '=');
$db_and = db_and()->condition('p.booking_eventid', $event->eid, '=')->condition($db_or);
$query->condition($db_and);
$query->fields('p')->fields('t');
//allow user to sort columns
$table_sort = $query->extend('TableSort')->orderbyHeader($header);
$result = $table_sort->execute();
foreach ($result as $person) {
$this_row = array();
//define the row for this person
//$this_row[] = $travel_link = l(t('Travel'), t('node/!id', array('!id' => $person->tid)));
//$this_row[] = l(t('Edit !id', array('!id' => $person->nid)), t('node/!id/edit', array('!id' => $person->nid)));
$this_row[] = l(t('!first !last', array('!first' => ucwords($person->booking_firstname), '!last' => ucwords($person->booking_lastname))),
t('node/!id', array('!id' => $person->tid))
);
$this_row[] = t('!state', array('!state' => $person->booking_state));
//$this_row[] = _booking_status_generate($person->booking_status);
$class = $person->booking_transport_type == 'Flying' ? "flying-row" : "normal-row";
//calculate the travel link
if ($person->tid > 0) {
//$travel_link = l(t('Travel'), t('node/!id/edit', array('!id' => $person->tid)));
$this_row[] = t('!transport', array('!transport' => $person->booking_transport_type));
$this_row[] = t('!train', array('!train' => $person->booking_transport_from_morriset_reqd == 1 ? 'Yes' : 'No'));
$this_row[] = t('!inflightnum', array('!inflightnum' => $person->booking_flightnum_inbound));
$this_row[] = t('!inflighttime', array('!inflighttime' =>
$person->booking_flight_datetime_inbound == 0 ? '' : format_date($person->booking_flight_datetime_inbound, 'custom', 'd/m/Y H:i')));
$this_row[] = t('!outflightnum', array('!outflightnum' => $person->booking_flightnum_outbound));
$this_row[] = t('!outflighttime', array('!outflighttime' =>
$person->booking_flight_datetime_outbound == 0 ? '' : format_date($person->booking_flight_datetime_outbound, 'custom', 'd/m/Y H:i')));
$this_row[] = t('!beforeaccom', array('!beforeaccom' => $person->booking_accom_before_reqd == 1 ? 'Yes' : 'No'));
$this_row[] = t('!afteraccom', array('!afteraccom' => $person->booking_accom_after_reqd == 1 ? 'Yes' : 'No'));
//mark people requiring accommodation in a different colour so they stand out more
if ($person->booking_accom_before_reqd == 1 || $person->booking_accom_after_reqd == 1) {
$class = "accomm-row";
}
}
else {
$this_row[] = "N/A";
//put in empty fields to fill up the table columns
for ($i = 0; $i < 7; $i++) {
$this_row[] = "";
}
}
$rows[] = array('data' => $this_row, 'class' => array($class));
}
$result = array (
'#attached' => array (
'css' => array(drupal_get_path('module', 'booking') . '/booking.css')
),
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'table' => array (
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#attributes' => array('id' => 'sort-table'),
//'#sticky' => FALSE,
)
);
return $result;
}
function booking_coming_page() {
global $event;
@@ -437,21 +538,17 @@ function booking_coming_page() {
$rows = array();
//work out whether to include the team colour in this page
if (variable_get('booking_publish_readinggroups', 0) == 1)
{
if (variable_get('booking_publish_readinggroups', 0) == 1) {
$header = array('Name', 'Team Colour', 'State');
}
else
{
else {
$header = array('Name', 'State');
}
//if configuration is set to show on lists even when no payment has been made, then include booking status of 0 (unpaid) or 1 (booked in)
//also ensure any committee members always show
if (variable_get('booking_auto_show_on_lists', 1) == 1)
{
if (variable_get('booking_auto_show_on_lists', 1) == 1) {
$or = db_or()->condition('p.booking_status', 0)->condition('p.booking_status', 1)>condition('p.booking_committee_member', 'Y');
$result = db_select('booking_person', 'p')
->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country'))
->condition($or)
@@ -461,13 +558,10 @@ function booking_coming_page() {
->orderBy('booking_lastname')
->orderBy('booking_firstname')
->execute();
}
else
{
else {
//payment must be made before someone will show up as booked in, but also include any committee member that might not have paid
$or = db_or()->condition('p.booking_status', 1)->condition('p.booking_committee_member', 'Y');
$result = db_select('booking_person', 'p')
->fields('p', array('booking_firstname', 'booking_lastname', 'booking_state', 'booking_readinggroup', 'booking_country'))
->condition($or)
@@ -479,13 +573,11 @@ function booking_coming_page() {
->execute();
}
foreach ($result as $person)
{
foreach ($result as $person) {
$state = $person->booking_country === variable_get('booking_default_country') ? $person->booking_state : $person->booking_country;
//if we're allowed to publish reading groups, specify them in the array element
if (variable_get('booking_publish_readinggroups', 0) == 1)
{
if (variable_get('booking_publish_readinggroups', 0) == 1) {
$rows[] = array(
t('!first !last', array('!first' => ucwords($person->booking_firstname),
'!last' => ucwords($person->booking_lastname))),
@@ -494,8 +586,7 @@ function booking_coming_page() {
);
}
//don't publish reading group information
else
{
else {
$rows[] = array(
t('!first !last', array('!first' => ucwords($person->booking_firstname),
'!last' => ucwords($person->booking_lastname))),
@@ -508,15 +599,12 @@ function booking_coming_page() {
//output the results
//check there were some bookings
if (count($rows) > 0)
{
if (count($rows) >= $booking_limit)
{
if (count($rows) > 0) {
if (count($rows) >= $booking_limit) {
//there is a waiting list
$output .= token_replace(variable_get('booking_whoscoming_pre_waitlist_text'), booking_define_tokens());
}
else
{
else {
//there's no waiting list
$output .= token_replace(variable_get('booking_whoscoming_pre_text'), booking_define_tokens());
}
@@ -524,8 +612,7 @@ function booking_coming_page() {
//theme the table of registrations
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes));
}
else
{
else {
//no bookings
$output .= token_replace(variable_get('booking_whoscoming_pre_noregistrations_text'), booking_define_tokens());
}
@@ -546,25 +633,17 @@ function booking_waitinglist_page() {
$booking_limit = variable_get('booking_regn_limit','350');
$rows = array();
$result = _booking_get_waitinglist();
/*
$result = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country
FROM (
SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date
FROM {booking_person} p, {booking_payment} pay
WHERE booking_status = 2 and booking_eventid = :eid and p.nid = pay.booking_person_nid
) AS booking
ORDER BY booking_payment_date',
array(':eid' => $event->eid));
*/
$result = db_query('SELECT DISTINCT nid, booking_firstname, booking_lastname, booking_state, booking_readinggroup, booking_country, booking_status
FROM (
SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date, p.booking_status
FROM {booking_person} p, {booking_payment} pay
WHERE p.booking_eventid = :eid and p.nid = pay.booking_person_nid and ( booking_status = 2 or booking_status = 4)
WHERE p.booking_eventid = :eid and p.nid = pay.booking_person_nid and ( p.booking_status = 2 or p.booking_status = 4)
) AS booking
ORDER BY booking_status, booking_payment_date',
array(':eid' => $event->eid));
*/
//watchdog('booking', "Who's coming query: @info", array('@info' => var_export($result, TRUE)));
@@ -603,6 +682,7 @@ function booking_waitinglist_page() {
return $output;
}
/*
function ucname($string) {
$string =ucwords(strtolower($string));
@@ -613,7 +693,7 @@ function ucname($string) {
}
return $string;
}
*/
/**
* Generate a CSV file as a report of all current registrations
@@ -621,17 +701,27 @@ function ucname($string) {
function booking_csv_report() {
global $event;
$name = 'bookings-' . format_date(time(), 'custom', 'Y-m-d-His');
$filename = file_directory_temp() . '/' . $name;
module_load_include('php', 'booking', 'libraries/xlsxwriter.class');
$filename = 'bookings-' . format_date(time(), 'custom', 'Y-m-d-His') . '.xlsx';
// List of style options at https://github.com/mk-j/PHP_XLSXWriter/issues/198
$header_style = array( 'border'=>'bottom','border-style'=>'thin', 'border-color'=>'#000000',
'valign'=>'top', 'font-style' => 'bold','font' => 'Calibri');
$row_style = array('font' => 'Calibri');
//$filename = file_directory_temp() . '/' . $name;
$csv = '';
$delimiter = ',';
$enclosure = '"';
$encloseAll = true;
$encloseAll = false;
$nullToMysqlNull = true;
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
$readinggroup_id = "";
//$readinggroup = "session" . variable_get('booking_readinggroup_id','7');
$studygroup_descriptions = array();
$header_array = array();
$rows = array();
//calculate fields to ignore in the output csv file
$builtin_fields_to_skip = array('booking_eventid');
@@ -639,18 +729,12 @@ function booking_csv_report() {
$fields_to_skip = array_merge($builtin_fields_to_skip, $custom_fields_to_skip);
//keep a list of any fields that we need to handle as dates
$date_fields = array('booking_dob');
$datetime_fields = array('booking_outflight_origin_ts', 'booking_outflight_destination_ts', 'booking_rtrnflight_origin_ts',
'booking_rtrnflight_destination_ts', 'booking_timestamp', 'booking_flight_datetime_inbound', 'booking_flight_datetime_outbound');
$number_only_fields = array('booking_postcode', 'booking_mobile', 'booking_phone');
//this isn't required since we already have the info directly as a field
//so there is no need to rewrite the ID field with a user-friendly description
//look up room location descriptions for presenting a friendly name rather than an ID
//$room_query = db_query("SELECT * FROM {booking_room_locations} WHERE booking_roomlocation_active = 'Y'");
//$room_locations = $room_query->fetchAllAssoc('lid');
$number_only_fields = array('booking_postcode', 'booking_mobile', 'booking_phone', 'booking_guardian_phone', 'booking_guardian_phone_alt', 'booking_price');
//look up the titles of the study groups and add to array for updating in the header
$studygroup_descriptions = array();
$studygroups_query = db_query("SELECT * FROM {booking_studygroup_list} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$studygroups = $studygroups_query->fetchAllAssoc('sid');
@@ -676,44 +760,63 @@ function booking_csv_report() {
//watchdog('booking', "CSV raw data: @info", array('@info' => var_export($result, TRUE)));
//write the header based on the first result
$header_array = array();
foreach (reset($result) as $key => $value)
{
if (in_array($key, $fields_to_skip))
foreach (reset($result) as $key => $value) {
if (in_array($key, $fields_to_skip)) {
continue;
}
/*
// Replace headings for study group sessions and roles with the name of the study group rather than just sessionN and sessionN_role etc
if (array_key_exists($key, $studygroup_descriptions))
{
$header_array[] = $studygroup_descriptions[$key];
if (variable_get('booking_friendly_csv_groupnames','0') == 1 && array_key_exists($key, $studygroup_descriptions)) {
//$header_array[] = $studygroup_descriptions[$key];
$heading = $studygroup_descriptions[$key];
$header_array[$heading] = 'string';
continue;
}
/*
// Apply data formatting as per https://github.com/mk-j/PHP_XLSXWriter
if (in_array($key, $datetime_fields)) {
// 11/09/2015 22:05
//$header_array[$key] = 'DD/MM/YYYY HH:MM';
$header_array[$key] = 'string';
}
elseif (in_array($key, $date_fields)) {
$header_array[$key] = 'string';
}
elseif (in_array($key, $number_only_fields)) {
$header_array[$key] = 'integer';
}
else {
$header_array[$key] = 'string';
}
*/
$header_array[] = $key;
$header_array[$key] = 'string';
//add in a special column for a processed version of the date of birth
if (strcmp($key,"booking_dob") == 0)
$header_array[] = "booking_dob_processed";
if (strcmp($key,"booking_dob") == 0) {
$header_array["booking_dob_processed"] = 'string';
}
//add in a calculated field for amount owing
if (strcmp($key, "nid") == 0) {
$header_array[] = "booking_amount_owing_gross";
$header_array[] = "booking_amount_owing_net";
}
$header_array["booking_amount_owing_gross"] = 'dollar';
$header_array["booking_amount_owing_net"] = 'dollar';
}
$header = implode( $delimiter, $header_array );
}
watchdog('booking_debug', "<pre>CSV report headers\n@info</pre>", array('@info' => print_r($header_array, true)));
//$header = implode( $delimiter, $header_array );
//$csv .= $header . "\n";
//watchdog('booking', "CSV header: @info", array('@info' => var_export($header_array, TRUE)));
//@fwrite($handle, $header . "\n");
$csv .= $header . "\n";
//each record
foreach ($result as $record) {
//watchdog('booking', "CSV raw data entry: @info", array('@info' => var_export($record, TRUE)));
$output = array();
//each keypair in the record
foreach ($record as $key => $value)
{
foreach ($record as $key => $value) {
//fields to skip
if (in_array($key, $fields_to_skip))
continue;
@@ -725,15 +828,19 @@ function booking_csv_report() {
}
//capitalise street name and suburb name
if ($key == 'booking_street' || $key == 'booking_suburb')
$value = ucname($value);
if ($key == 'booking_street' || $key == 'booking_suburb') {
$value = _booking_ucname($value);
}
//handle dates
if ($key == 'booking_dob') {
$output[] = format_date($value, 'custom', 'd/m/Y');
$output[] = '"' . _booking_avg_age($value, 1, $event->booking_event_start) . '"';
// Add in the processed DOB
$output[] = _booking_avg_age($value, 1, $event->booking_event_start);
//$output[] = '"' . _booking_avg_age($value, 1, $event->booking_event_start) . '"';
continue;
}
if ($key == 'booking_passport_expiry_date') {
$output[] = format_date($value, 'custom', 'd/m/Y');
continue;
@@ -756,7 +863,8 @@ function booking_csv_report() {
$output[] = _booking_status_generate($value);
continue;
}
//studygroup ygroup session roles
//studygroup group session roles
if (preg_match("/session\d+_role/", $key))
{
$output[] = _booking_studygroup_role_lookup($value);
@@ -785,8 +893,7 @@ function booking_csv_report() {
}
//add in the amount owing using the nid as the key
if ($key == 'nid')
{
if ($key == 'nid') {
$output[] = $value;
//add the amount owing firstly including paypal fees then excluding them
//bit of a hack since this can never be excluded from the report
@@ -796,37 +903,47 @@ function booking_csv_report() {
}
// Enclose fields containing $delimiter, $enclosure or whitespace
if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $value ) ) {
$output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure;
}
else {
$output[] = $field;
}
//if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $value ) ) {
// $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $value) . $enclosure;
//}
//else {
$output[] = $value;
//}
} // End of record processing
$rows[] = $output;
//$row = implode($delimiter, $output) . "\n";
//$csv .= $row;
}
$row = implode($delimiter, $output) . "\n";
//watchdog('booking_debug', "<pre>CSV report spreadsheet rows\n@info</pre>", array('@info' => print_r( $rows, true)));
//@fwrite($handle, $row);
$csv .= $row;
//$index++;
// Create headers for Excel spreadsheet
header('Content-disposition: attachment; filename="'.XLSXWriter::sanitize_filename($filename).'"');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$sheetname = $event->booking_eventname;
$writer = new XLSXWriter();
$writer->setAuthor($event->booking_eventname);
//Add the header row
$writer->writeSheetHeader($sheetname, $header_array, $header_style);
//Add the data
foreach($rows as $row) {
$writer->writeSheetRow($sheetname, $row, $row_style);
}
//@fclose($handle);
$writer->writeToStdOut();
exit(0);
//see http://stackoverflow.com/questions/4348802/how-can-i-output-a-utf-8-csv-in-php-that-excel-will-read-properly
// but none of these options seem to work
drupal_add_http_header("Content-type", "application/octet-stream; charset=utf-8");
//drupal_add_http_header("Content-type", "application/octet-stream; charset=UTF-16LE");
//drupal_add_http_header("Content-Type: application/vnd.ms-excel");
drupal_add_http_header("Content-Disposition", "attachment; filename=" . $name . ".csv");
// @readfile($filename);
//print chr(255) . chr(254);
//print 'sep=,' . "\n";
print $csv;
//print mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
//@unlink($filename);
exit(0);
//drupal_add_http_header("Content-type", "application/octet-stream; charset=utf-8");
//drupal_add_http_header("Content-Disposition", "attachment; filename=" . $name . ".csv");
//print $csv;
//exit(0);
}

View File

@@ -420,15 +420,15 @@ function booking_rooms_view_form($node, &$form_state, $location_id) {
return "";
}
//@todo reduce the number of queries by using some joins
$location_description = db_query("SELECT booking_roomlocation_descrip FROM {booking_room_locations} where lid = :id",
array(':id' => $location_id))
->fetchObject();
//$prefix = t("<h2>Room Allocations for !room</h2>", array('!room' => _booking_room_location_lookup($location_id)));
//use the query result to include a human friendly group name
$prefix = t("<h2>Room Allocations for !room</h2>", array('!room' => $location_description->booking_roomlocation_descrip));
//query for room definitions
$room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid",
$room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid ORDER BY booking_room_number",
array(':lid' => $location_id));
//query for existing room allocations
@@ -446,6 +446,8 @@ function booking_rooms_view_form($node, &$form_state, $location_id) {
//define the header
$header = array(
'booking_room_number' => array('data' => t('Room Number')),
'booking_room_description' => array('data' => t('Room Label')),
'booking_room_ensuite' => array('data' => t('Ensuite?')),
'booking_room_singlebed' => array('data' => t('Single Bed')),
'booking_room_doublebed_p1' => array('data' => t('Double Bed Person 1')),
'booking_room_doublebed_p2' => array('data' => t('Double Bed Person 2')),
@@ -453,89 +455,75 @@ function booking_rooms_view_form($node, &$form_state, $location_id) {
'booking_room_queenbed_p2' => array('data' => t('Queen Bed Person 2')),
);
foreach ($room_query as $data)
{
//load the existing bed mappings for this room
$existing_beds = array();
for ($i = 1; $i <= 3; $i++)
{
foreach ($room_mapping as $mapping)
{
//check that the room id in the mapping table matches the room that we're currently adding to the table
//and also the bed type matches the first dimension in the array
if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i)
{
$existing_beds[$i][] = $mapping->booking_nodeid;
}
}
}
//define the default fields in a table row
$default_row = array();
$default_row['booking_room_number'] = "";
$default_row['booking_room_description'] = "";
$default_row['booking_room_ensuite'] = "";
$default_row['booking_room_singlebed'] = "";
$default_row['booking_room_doublebed_p1'] = "";
$default_row['booking_room_doublebed_p2'] = "";
$default_row['booking_room_queenbed_p1'] = "";
$default_row['booking_room_queenbed_p2'] = "";
//create a row that contains just the room location and number
foreach ($room_query as $data) {
//create a row that contains just the room location and number and the custom css id for a separating line between the rooms
$new_row = _booking_clone_array($default_row);
$new_row['booking_room_number'] = $data->booking_room_number;
$new_row['booking_room_description'] = $data->booking_room_description;
$new_row['booking_room_ensuite'] = $data->booking_room_ensuite == 'Y' ? "Yes" : "No";
$rows[] = array(
'data' => array(
$data->booking_room_number,
"",
"",
"",
"",
"",
),
'data' => $new_row,
'id' => array("new-group-row"),
);
//load the existing bed mappings for this room
$existing_beds = array();
for ($i = 1; $i <= 3; $i++) {
foreach ($room_mapping as $mapping) {
//check that the room id in the mapping table matches the room that we're currently adding to the table
//and also the bed type matches the first dimension in the array
if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i) {
$existing_beds[$i][] = $mapping->booking_nodeid;
}
}
} //end creating existing room mappings for this room
//create an additional row for each single bed
for ($i = 0; $i < $data->booking_room_singlebeds; $i++)
{
for ($i = 0; $i < $data->booking_room_singlebeds; $i++) {
//retrieve the default value if one exists
$nid = (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : 0;
$new_row = _booking_clone_array($default_row);
$new_row['booking_room_singlebed'] = _booking_rooms_view_formatperson($attendees, $nid);
$rows[] = array(
'data' => array(
"",
_booking_rooms_view_formatperson($attendees, $nid),
"",
"",
"",
"",
),
'data' => $new_row,
);
}
//create an additional row for each double bed
//$j is our counter that increments twice as fast as $i to cater for both beds
$j = 0;
for ($i = 0; $i < $data->booking_room_doublebeds; $i++)
{
for ($i = 0; $i < $data->booking_room_doublebeds; $i++) {
$new_row = _booking_clone_array($default_row);
$new_row['booking_room_doublebed_p1'] = _booking_rooms_view_formatperson($attendees, (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0);
$new_row['booking_room_doublebed_p2'] = _booking_rooms_view_formatperson($attendees, (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0);
$rows[] = array(
'data' => array(
"",
"",
_booking_rooms_view_formatperson($attendees, (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0),
_booking_rooms_view_formatperson($attendees, (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0),
"",
"",
),
'data' => $new_row,
);
}
//create an additional row for each queen bed
//$j is our counter that increments twice as fast as $i to cater for both beds
$j = 0;
for ($i = 1; $i <= $data->booking_room_queenbeds; $i++)
{
for ($i = 1; $i <= $data->booking_room_queenbeds; $i++) {
$new_row = _booking_clone_array($default_row);
$new_row['booking_room_queenbed_p1'] = _booking_rooms_view_formatperson($attendees, (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0);
$new_row['booking_room_queenbed_p2'] = _booking_rooms_view_formatperson($attendees, (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0);
$rows[] = array(
'data' => array(
"",
"",
"",
"",
_booking_rooms_view_formatperson($attendees, (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0),
_booking_rooms_view_formatperson($attendees, (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0),
),
'data' => $new_row,
);
}
}
} //end room iteration loop
//watchdog('booking', "<pre>Room assignment report rows:\n@info</pre>", array('@info' => print_r( $rows, true)));
@@ -570,8 +558,7 @@ function _booking_rooms_view_formatperson(&$attendees, $nid) {
$output = "Empty";
if ($nid > 0 && !empty($attendees[$nid]))
{
if ($nid > 0 && !empty($attendees[$nid])) {
$output = $attendees[$nid]->booking_firstname . " " . $attendees[$nid]->booking_lastname;
}

View File

@@ -33,6 +33,7 @@ function booking_room_view_summary() {
//output everything
$output .= t("<h3>!event Room Locations</h3>", array('!event' => $event->booking_eventname));
$output .= t("<p>Use the link above to view room mate preferences and room allocations.</p>");
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes));
return $output;
@@ -225,7 +226,8 @@ function booking_rooms_view_definitions() {
$definition_query->join('booking_room_locations', 'l', 'l.lid = r.booking_room_location_id');
$definition_query->condition('l.booking_roomlocation_active', 'Y', '=')
->fields('r')
->fields('l');
->fields('l')
->orderBy('lid')->orderBy('booking_room_number');
$definition_result = $definition_query->execute();
$location_header = array (
@@ -237,6 +239,7 @@ function booking_rooms_view_definitions() {
$definition_header = array (
'booking_room_location_description' => t('Room Location'),
'booking_room_number' => t('Room Number'),
'booking_room_description' => t('Room Description'),
'booking_room_singlebeds' => t('Number Single Beds'),
'booking_room_doublebeds' => t('Number Double Beds'),
'booking_room_queenbeds' => t('Number Queen Beds'),
@@ -244,8 +247,7 @@ function booking_rooms_view_definitions() {
'booking_room_edit' => t('Edit Room'),
);
foreach($location_result as $data)
{
foreach($location_result as $data) {
$location_rows[] = array (
$data->booking_roomlocation_descrip,
$data->booking_roomlocation_active == 'Y' ? 'Yes' : 'No',
@@ -253,12 +255,12 @@ function booking_rooms_view_definitions() {
);
}
foreach($definition_result as $data)
{
foreach($definition_result as $data) {
$definition_rows[] = array (
//_booking_room_location_lookup($data->booking_room_location_id),
$data->booking_roomlocation_descrip,
$data->booking_room_number,
$data->booking_room_description,
$data->booking_room_singlebeds,
$data->booking_room_doublebeds,
$data->booking_room_queenbeds,
@@ -309,31 +311,28 @@ function booking_rooms_definition_form($node, &$form_state, $create, $room_id =
$query = db_query("SELECT * FROM {booking_room_locations} where booking_roomlocation_active='Y'");
foreach($query as $row)
{
foreach($query as $row) {
$location_options[$row->lid] = $row->booking_roomlocation_descrip;
}
if ($create == true)
{
if ($create == true) {
$data = $node;
$prefix = t("<p>Create new room defintion.</p>");
//watchdog('booking', 'Creating new room definition: @info', array ('@info' => var_export($node, TRUE)));
}
else
{
else {
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $room_id)) {
drupal_set_message("Error: Invalid room ID supplied. Unable to update room definition.", 'error', FALSE);
drupal_goto('admin/config/booking/rooms');
return "";
}
$prefix = t("<p>Update the room defintions.</p>");
//$data = $form_state['input'];
$data = db_query("SELECT * FROM {booking_room_definition} WHERE rid = :id",
array(':id' => $room_id))
$data = db_query("SELECT * FROM {booking_room_definition} WHERE rid = :id", array(':id' => $room_id))
->fetchObject();
$prefix = t("<p>Update the room defintions.</p>");
//add this to the form in a hidden field so we can update the right price
$form['booking_rid'] = array(
'#type' => 'hidden',
@@ -343,13 +342,12 @@ function booking_rooms_definition_form($node, &$form_state, $create, $room_id =
}
//create the options array for bed counts
for ($i = 0; $i <= 15; $i++)
for ($i = 0; $i <= 15; $i++) {
$bedcount_options[$i] = $i;
}
//define the form for adding to the room definitions
if(!isset($form_state['storage']['confirm'])) {
$form[] = array (
'first_heading' => array(
'#type' => 'markup',
@@ -370,6 +368,13 @@ function booking_rooms_definition_form($node, &$form_state, $create, $room_id =
'#maxlength' => 10,
'#default_value' => !empty($data->booking_room_number) ? $data->booking_room_number : '',
);
$form['booking_room_description'] = array(
'#type' => 'textfield',
'#title' => t('Specify room label (not mandatory)'),
'#size' => 50,
'#maxlength' => 100,
'#default_value' => !empty($data->booking_room_description) ? $data->booking_room_description : '',
);
$form['booking_room_singlebeds'] = array(
'#type' => 'select',
'#title' => t('Specify number of single beds'),
@@ -394,21 +399,18 @@ function booking_rooms_definition_form($node, &$form_state, $create, $room_id =
'#default_value' => (!empty($data->booking_room_ensuite) && $data->booking_room_ensuite == 'Y') ? 1 : 0,
);
if ($create == true)
{
$form['submit'] = array
(
if ($create == true) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add Room'),
);
} else {
$form['Update'] = array
(
}
else {
$form['Update'] = array(
'#type' => 'submit',
'#value' => t('Update Room'),
);
$form['Delete'] = array
(
$form['Delete'] = array(
'#type' => 'submit',
'#value' => t('Delete Room'),
);
@@ -418,11 +420,25 @@ function booking_rooms_definition_form($node, &$form_state, $create, $room_id =
'form' => $form,
);
}
else
{
else {
return confirm_form($form, "Are you sure you wish to delete room definition with id " . $room_id . "?",
current_path(), NULL, "Delete Room");
}
}
/**
* Validate the form for adding room definitions
*/
function booking_rooms_definition_form_validate($form, $form_state) {
//make sure room number is numerical
$values = $form_state['input'];
if ($form_state['values']['op'] != 'Delete Room') {
if (isset($values['booking_room_number']) && (! is_numeric($values['booking_room_number']))) {
form_set_error('booking_room_number', t('Room number must be numeric. If you need to use a more descriptive label, please use the room label field.'));
watchdog('booking_debug', "<pre>Room definition submission:\n@info</pre>", array('@info' => print_r( $form_state, true)));
}
}
}
@@ -437,14 +453,12 @@ function booking_rooms_definition_form_submit($form, &$form_state) {
//watchdog('booking', "<pre>Room definition submission:\n@info</pre>", array('@info' => print_r( $form_state, true)));
//if we're deleting, add the confirmation to the form if it hasn't been defined yet
if($form_state['values']['op'] == 'Delete Room' && (!isset($form_state['storage']['confirm'])))
{
if($form_state['values']['op'] == 'Delete Room' && (!isset($form_state['storage']['confirm']))) {
//watchdog('booking', "<pre>Room deletion confirmation being set:\n@info</pre>", array('@info' => print_r( $form_state, true)));
$form_state['storage']['confirm'] = TRUE;
$form_state['rebuild'] = TRUE;
}
elseif ($form_state['values']['op'] == 'Delete Room')
{
elseif ($form_state['values']['op'] == 'Delete Room') {
//delete the room
watchdog('booking', "Deleting room ID !rid", array('!rid' => $values['booking_rid']));
@@ -455,12 +469,12 @@ function booking_rooms_definition_form_submit($form, &$form_state) {
drupal_set_message('Deleted room id ' . $values['booking_rid'] );
$form_state['redirect'] = $redirect_path;
}
elseif ($form_state['values']['op'] == 'Update Room')
{
elseif ($form_state['values']['op'] == 'Update Room') {
$result = db_update('booking_room_definition')
->fields(array(
'booking_room_location_id' => $values['booking_room_location_id'],
'booking_room_number' => $values['booking_room_number'],
'booking_room_description' => $values['booking_room_description'],
'booking_room_singlebeds' => $values['booking_room_singlebeds'],
'booking_room_doublebeds' => $values['booking_room_doublebeds'],
'booking_room_queenbeds' => $values['booking_room_queenbeds'],
@@ -477,6 +491,7 @@ function booking_rooms_definition_form_submit($form, &$form_state) {
->fields(array(
'booking_room_location_id' => $values['booking_room_location_id'],
'booking_room_number' => $values['booking_room_number'],
'booking_room_description' => $values['booking_room_description'],
'booking_room_singlebeds' => $values['booking_room_singlebeds'],
'booking_room_doublebeds' => $values['booking_room_doublebeds'],
'booking_room_queenbeds' => $values['booking_room_queenbeds'],

View File

@@ -11,7 +11,10 @@ function _booking_rooms_name_autocomplete($string) {
$query = db_select('booking_person', 'p')
->fields('p', array('nid', 'booking_firstname', 'booking_lastname'));
$db_or = db_or()->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE');
$db_or = db_or()
->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.nid', $string, "=");
$db_and = db_and()->condition($db_or)->condition('p.booking_eventid', $event->eid, '=');
$result = $query->condition($db_and)
->execute();
@@ -68,6 +71,8 @@ function booking_rooms_allocate_form($node, &$form_state, $location_id) {
$header = array (
'booking_room_location' => array('data' => t('Room Location'), 'field' => 'booking_room_location_id'),
'booking_room_number' => array('data' => t('Room Number')),
'booking_room_description' => array('data' => t('Room Label')),
'booking_room_ensuite' => array('data' => t('Ensuite?')),
'booking_room_singlebed' => array('data' => t('Single Bed')),
'booking_room_doublebed_p1' => array('data' => t('Double Bed Person 1')),
'booking_room_doublebed_p2' => array('data' => t('Double Bed Person 2')),
@@ -94,24 +99,22 @@ function booking_rooms_allocate_form($node, &$form_state, $location_id) {
$default_row = array();
$default_row['booking_room_location'] = "";
$default_row['booking_room_number'] = "";
$default_row['booking_room_description'] = "";
$default_row['booking_room_ensuite'] = "";
$default_row['booking_room_singlebed'] = "";
$default_row['booking_room_doublebed_p1'] = "";
$default_row['booking_room_doublebed_p2'] = "";
$default_row['booking_room_queenbed_p1'] = "";
$default_row['booking_room_queenbed_p2'] = "";
foreach ($room_query as $data)
{
foreach ($room_query as $data) {
//create an array representing the existing bed mappings for this room
$existing_beds = array();
for ($i = 1; $i <= 3; $i++)
{
foreach ($room_mapping as $mapping)
{
for ($i = 1; $i <= 3; $i++) {
foreach ($room_mapping as $mapping) {
//check that the room id in the mapping table matches the room that we're currently adding to the table
//and also the bed type matches the first dimension in the array
if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i)
{
if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i) {
$existing_beds[$i][] = $mapping->booking_lastname . ', ' . $mapping->booking_firstname . ' [' . $mapping->booking_nodeid . ']';
}
}
@@ -122,6 +125,8 @@ function booking_rooms_allocate_form($node, &$form_state, $location_id) {
//$new_row['booking_room_location'] = _booking_room_location_lookup($data->booking_room_location_id);
$new_row['booking_room_location'] = $data->booking_roomlocation_descrip;
$new_row['booking_room_number'] = $data->booking_room_number;
$new_row['booking_room_description'] = $data->booking_room_description;
$new_row['booking_room_ensuite'] = $data->booking_room_ensuite == 'Y' ? "Yes" : "No";
$form['rooms']['#rows'][$counter++] = array(
'data' => $new_row,
'id' => array("new-group-row"),

65
booking.stripe-old.js Normal file
View File

@@ -0,0 +1,65 @@
(function($) {
$(function() {
Stripe.setPublishableKey(Drupal.settings.booking_stripeform.pubkey);
});
Drupal.behaviors.booking_stripeform = {
attach: function(context, settings) {
$("#" + settings.booking_stripeform.form_selector, context).submit(function(e) {
e.preventDefault();
var $form = $(this);
var $obj;
var $submitBtn = $("#edit-submit", context);
settings.booking_stripeform.submitBtnText = $submitBtn.val();
try {
var $ccnum = $(':input[data-stripe="number"]', $form);
var $exp_month = $(':input[data-stripe="exp-month"]', $form);
var $exp_year = $(':input[data-stripe="exp-year"]', $form);
var $cvc = $(':input[data-stripe="cvc"]', $form);
if(!Stripe.card.validateCardNumber($(':input[data-stripe="number"]', $form).val())) {
$obj = $ccnum;
throw "Invalid credit card number";
}
if(!Stripe.card.validateExpiry($exp_month.val(), $exp_year.val())) {
$obj = $exp_month;
throw "Invalid expiration month/year";
}
if(!Stripe.card.validateCVC($cvc.val())) {
$obj = $cvc;
throw "Invalid CVC";
}
} catch(err) {
$.each([$ccnum, $exp_month, $exp_year, $cvc], function(i, e) {
e.addClass('error');
});
$obj.parents('div.control-group').toggleClass('error');
reportError(err, $obj);
return false;
}
$submitBtn.val('Please wait...').attr('disabled', true);
Stripe.createToken($form, stripeResponseHandler);
return false;
});
}
}
var stripeResponseHandler = function(status, response) {
var $form = $("#" + Drupal.settings.booking_stripeform.form_selector);
if (response.error) {
alert(response.error.message);
} else {
// token contains id, last4, and card type
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$('input[name=stripeToken]', $form).val(token);
// and submit
$form.get(0).submit();
}
};
/**
* Uses Bootstrap's popover to alert the user.
*/
function reportError(msg, $el) {
console.log([$el, msg]);
}
}(jQuery));

330
booking.stripe.inc Normal file
View File

@@ -0,0 +1,330 @@
<?php
/**
* @file
* Functions for stripe payment integration
* @see https://github.com/ericthelast/drupal-stripe-form and https://www.webomelette.com/drupal-stripe-integration
*/
/**
* Get the current stripe api public key
*/
function _booking_get_stripe_public_key() {
if (variable_get('booking_stripe_testmode', 0) == 1) {
return variable_get('booking_stripe_test_public_key', '');
}
else {
return variable_get('booking_stripe_live_public_key', '');
}
}
/**
* Get the current stripe api private key
*/
function _booking_get_stripe_private_key() {
if (variable_get('booking_stripe_testmode', 0) == 1) {
return variable_get('booking_stripe_test_secret_key', '');
}
else {
return variable_get('booking_stripe_live_secret_key', '');
}
}
/**
* Helper function to calculate stripe transaction fees
*/
function _booking_add_stripe_fees($amount, $country) {
//add the 30 cent fixed cost
$result = '0.00';
$result = (float) ($amount + (float) variable_get('booking_stripe_transaction_fee_fixedcost', '0.3'));
//and the 2.6 percent transaction fee for australian transaction with no currency conversion
if ($country == variable_get('booking_default_country', 'Australia')) {
$percentage = (float) variable_get('booking_stripe_transaction_fee_percentage', '1.75');
} else {
$percentage = (float) variable_get('booking_stripe_transaction_fee_percentage_intl', '2.9');
}
//apply the percentage
$percentage = (float) $percentage / 100;
$result = $result / (1 - $percentage);
//return result
return $result;
}
/**
* Helper function to generate paypal form for payments
*/
function _booking_stripe_form($person, $invoiceid, $net_amount_owing, $button_text) {
$payment_form = drupal_get_form('booking_stripe_form', $person, $invoiceid, $net_amount_owing, $button_text);
return drupal_render($payment_form);
}
function booking_stripe_form($node, &$form_state, $person, $invoiceid, $net_amount_owing, $button_text) {
global $event;
$settings = array();
$form = array();
//set some values for our internal stripe library to help process the form
//these will be used by the attached js from booking-strip library to identify which parts of the form to process
$setting['booking_stripe'] = array(
'pubkey' => _booking_get_stripe_public_key(),
'form_selector' => str_replace('_', '-', __FUNCTION__),
'name' => $event->booking_eventname,
'image' => variable_get('booking_stripe_logo', ''),
'payment_button_label' => '{{amount}} (plus fees)',
);
//attach settings and javascript to the form
$form['#attached'] = array(
'js' => array(
array('data' => $setting, 'type' => 'setting'),
),
'library' => array(
array('booking', 'booking-stripe'),
),
);
//paypal specific settings
$vars = array(
'nid' => $person->nid,
'email' => $person->booking_email,
'description' => $event->booking_eventname . ' ' . $person->booking_price_descrip,
'invoice' => $invoiceid,
'amount' => $net_amount_owing,
'gross_amount' => number_format(_booking_add_stripe_fees($net_amount_owing, $person->booking_country), 2, '.', ''),
'foreign_gross_amount' => number_format(_booking_add_stripe_fees($net_amount_owing, 'FakeCountry'), 2, '.', ''),
'last_name' => $person->booking_lastname,
'first_name' => $person->booking_firstname,
'uuid' => $person->booking_tempid,
'token_id' => '',
'token_email' => '',
'token_client_ip' => '',
'card_brand' => '',
'card_country' => '',
'card_cvc_check' => '',
'card_address_zip_check' => '',
);
//turn the array into a form
foreach($vars as $name => $value) {
$form[$name] = array(
'#type' => 'hidden',
'#value' => $value,
);
};
$form['submit'] = array(
'#id' => 'stripe-submit',
'#type' => 'button',
'#value' => t($button_text),
);
$form['#after_build'][] = 'booking_stripe_add_final_validation';
//watchdog('booking', 'Booking Balance payment: @info', array ('@info' => var_export($form, TRUE)));
return $form;
}
/**
* Tries to add final validation after all else has been added through alters.
*/
function booking_stripe_add_final_validation($form) {
$form['#validate'][] = 'booking_stripe_validate_form_payment';
return $form;
}
/**
* Form validation callback.
*/
function booking_stripe_checkout_form_validate($form, &$form_state) {
// Validate normal form elements as needed.
}
/**
* Processes the stripe payment.
*
* We do this here so that if the payment fails,
* we're still in a validation stage and can return
* early. If success, we'll pass the charge on
* to the submission callback.
*/
function booking_stripe_validate_form_payment($form, &$form_state) {
global $event;
if($errors = form_get_errors()) {
//@todo log an error via watchdog
return;
}
$path = libraries_get_path('stripe');
require_once($path . '/init.php');
\Stripe\Stripe::setApiKey(_booking_get_stripe_private_key());
//get values from original form
//@todo sanitise this input
$token = (isset($form_state['input']['token_id']) ? $form_state['input']['token_id'] : '');
$amount = (isset($form_state['input']['gross_amount']) ? $form_state['input']['gross_amount'] : '');
$invoice = (isset($form_state['input']['invoice']) ? $form_state['input']['invoice'] : '');
$nid = (isset($form_state['input']['nid']) ? $form_state['input']['nid'] : '');
$tempid= (isset($form_state['input']['uuid']) ? $form_state['input']['uuid'] : '');
$last_name = (isset($form_state['input']['last_name']) ? $form_state['input']['last_name'] : '');
$first_name = (isset($form_state['input']['first_name']) ? $form_state['input']['first_name'] : '');
$card_brand = (isset($form_state['input']['card_brand']) ? $form_state['input']['card_brand'] : '');
$card_country = (isset($form_state['input']['card_country']) ? $form_state['input']['card_country'] : '');
//if card issuer is american express then the transaction fee charged should be the international rate
if ($card_brand === 'American Express') {
$person = node_load($nid);
$amount = (isset($form_state['input']['foreign_gross_amount']) ? $form_state['input']['foreign_gross_amount'] : $amount);
watchdog('booking_debug', "Detected Amex card use, setting amount to !amount", array('!amount' => $amount));
}
//if card is issued from a different country then apply the international rate also
//@todo figure out a better way of matching country name to country code
// probably via https://api.drupal.org/api/drupal/includes%21locale.inc/function/country_get_list/7.x
//NOTE! This will result in incorrect charge amounts when using the test API due to a stripe bug
//since the australian test card number gets charged 2.9% instead of 1.75%
elseif (variable_get('booking_default_country', 'Australia') === 'Australia' && $card_country !== 'AU') {
$person = node_load($nid);
$amount = (isset($form_state['input']['foreign_gross_amount']) ? $form_state['input']['foreign_gross_amount'] : $amount);
watchdog('booking_debug', "Detected foreign card use (country !country), setting amount to !amount",
array('!country' => $card_country, '!amount' => $amount));
}
// Create the charge on Stripe's servers - this will charge the user's card
try {
$charge = \Stripe\Charge::create(array(
"amount" => $amount * 100,
"currency" => "aud",
"card" => $token,
"statement_descriptor" => substr($event->booking_eventname, 0, 21), //this field is limited to 22 characters
"expand" => array('balance_transaction'),
"description" => $form_state['input']['description'],
"receipt_email" => $form_state['input']['email'],
"metadata" => array(
"invoice" => $invoice,
"nid" => $nid,
"last_name" => $last_name,
"first_name" => $first_name,
),
));
watchdog('booking_debug', "<pre>Stripe payment charge results:\n@info</pre>", array('@info' => print_r( $charge->toJSON(), true)));
if ($charge && $charge->paid) {
//watchdog('booking_debug', 'Charge created successfully');
_booking_process_stripe_payment($charge, $token);
//$form_state['stripeform_charge'] = $charge;
// @todo call _booking_process_stripe_payment to store payment
drupal_goto('bookingfinal/' . $tempid);
}
else {
watchdog('booking', 'Charge was not created successfully');
drupal_set_message('Card does not seem to have been charged successfully. Please try again', 'error');
}
}
catch(\Stripe\Error\Card $e) {
//$e_json = $e->getJsonBody();
//$error = $e_json['error'];
watchdog('booking', "<pre>Detected exception processing Stripe payment (!message)\n@info</pre>",
array('!message' => $e->getMessage(), '@info' => $e->getTraceAsString() ));
drupal_set_message($e->getMessage(), 'error');
}
catch (\Stripe\Error\ApiConnection $e) {
watchdog('booking', "<pre>Detected exception processing Stripe payment (!message)\n@info</pre>",
array('!message' => $e->getMessage(), '@info' => $e->getTraceAsString() ));
drupal_set_message($e->getMessage(), 'error');
}
catch (\Stripe\Error\Api $e) {
watchdog('booking', "<pre>Detected exception processing Stripe payment (!message)\n@info</pre>",
array('!message' => $e->getMessage(), '@info' => $e->getTraceAsString() ));
drupal_set_message($e->getMessage(), 'error');
}
catch (\Stripe\Exception\CardException $e) {
watchdog('booking', "<pre>Detected exception processing Stripe payment (!message)\n@info</pre>",
array('!message' => $e->getMessage(), '@info' => $e->getTraceAsString()));
drupal_set_message($e->getMessage(), 'error');
}
}
function _booking_process_stripe_payment(&$charge, $token) {
global $event;
$balance_payment = false;
$amount_owing = 0;
//$invoice = $data->metadata;
//verify the status of the charge
if (empty($charge->status) || ($charge->status != 'succeeded')) {
$successful = FALSE;
}
else {
$successful = TRUE;
}
//extract the person node id from the invoice
$pos = strpos($charge->metadata->invoice, "_");
if (($pos === false) || ($pos == 0)) {
watchdog('booking', 'Unable to process payment with invalid invoice information: !id', array('!id' => $charge->metadata->invoice), WATCHDOG_ERROR);
return;
}
//get the part of the invoice up to the first underscore
$nid = substr($charge->metadata->invoice, 0, $pos);
//get the data between the first and second underscore
$eid = substr($charge->metadata->invoice, $pos + 1, strrpos($charge->metadata->invoice, "_") - $pos - 1);
if (substr($eid,0,3) == "bal") {
$balance_payment = true;
watchdog('booking_debug', 'Balance payment via stripe for user with node id: !id and status !status.',
array('!id' => $nid, '!status' => $charge->status));
}
else {
watchdog('booking_debug', 'Initial payment via stripe for user with node id: !id and status !status.',
array('!id' => $nid, '!status' => $charge->status));
}
//this shouldn't ever happen, since stripe is sending this notification synchronously
//but just in case, check for an existing transaction that matches this one
$duplicate_check = db_query("SELECT payid, booking_person_nid FROM {booking_payment} where booking_ipn_track_id = :ipn_id ",
array(':ipn_id' => $charge->id))->fetchObject();
if ($duplicate_check) {
watchdog('booking', 'Detected duplicate stripe transaction notifications for transaction id !id, registration id !nid',
array('!id' => $charge->id, '!nid' => $nid), WATCHDOG_ERROR);
return;
}
$gross_amount = $charge->amount / 100;
$result = db_insert('booking_payment')
->fields(array(
'booking_person_nid' => $nid,
'booking_eventid' => $event->eid,
'booking_mc_gross' => $gross_amount,
'booking_mc_currency' => $charge->balance_transaction->currency,
'booking_mc_fee' => $charge->balance_transaction->fee / 100,
'booking_invoice' => $charge->metadata->invoice,
'booking_payer_id' => $charge->source->id,
'booking_payment_date' => $charge->created,
'booking_payment_status' => $charge->status,
'booking_first_name' => $charge->metadata->first_name,
'booking_last_name' => $charge->metadata->last_name,
'booking_buyer_email' => $charge->receipt_email,
'booking_item_name' => $charge->description,
'booking_ipn_track_id' => $charge->id,
'booking_stripe_response' => $charge->toJSON(),
))
->execute();
//Get the person's info so we can update their total amount paid and booking status
$person = node_load($nid);
//check if we found a person matching this payment
if ($person) {
watchdog('booking', 'Found matching user with node id: !id; event id: !eid; existing payment !payment',
array('!id' => $nid, '!eid' => $eid, '!payment' => $person->booking_amount_paid));
_booking_process_person_payment($person, $gross_amount, $balance_payment);
}
else {
//couldn't find a matching nid for this invoice
watchdog('booking', "Unable to process payment for user with node id: '!id'", array('!id' => $nid), WATCHDOG_ERROR);
//db_query("UPDATE {booking_person} SET booking_tempid='' WHERE nid = %d", $nid);
}
}

52
booking.stripe.js Normal file
View File

@@ -0,0 +1,52 @@
jQuery(document).ready(function($) {
var $settings = Drupal.settings.booking_stripe;
var $stripeForm = $("#" + $settings.form_selector);
var handler = StripeCheckout.configure({
key: $settings.pubkey,
image: $settings.image,
locale: 'auto',
token: function(token) {
try {
//store relevant parts of the returned token into hidden form elements
$(':input[name="token_id"]', $stripeForm).val(token.id);
$(':input[name="token_email"]', $stripeForm).val(token.email);
$(':input[name="token_client_ip"]', $stripeForm).val(token.client_ip);
$(':input[name="card_brand"]', $stripeForm).val(token.card.brand);
$(':input[name="card_country"]', $stripeForm).val(token.card.country);
$(':input[name="card_cvc_check"]', $stripeForm).val(token.card.cvc_check);
$(':input[name="card_address_zip_check"]', $stripeForm).val(token.card.address_zip_check);
$stripeForm.get(0).submit();
}
catch(err) {
console.log([err]);
alert(err.message);
}
}
});
$('.form-submit').click(function (e) {
var $settings = Drupal.settings.booking_stripe;
var $stripeForm = $("#" + $settings.form_selector);
var $amount = $(':input[name="amount"]', $stripeForm).val() * 100;
handler.open({
name: $settings.name,
panelLabel: $settings.payment_button_label,
currency: "AUD",
description: $(':input[name="description"]', $stripeForm).val(),
email: $(':input[name="email"]', $stripeForm).val(),
amount: Math.round($amount),
zipCode: true,
closed: function() {
//document.getElementById("booking_stripe_form").submit();
}
});
e.preventDefault();
});
/*
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
*/
});

View File

@@ -2,11 +2,9 @@
/**
* @file
* Functions for calculating leaders and helpers for discussion groups
* Functions for automatically calculating leaders and helpers for discussion groups
*/
/**
* Function for calculating and assigning leaders and helpers to active study group sessions
*/
@@ -66,20 +64,16 @@ function _booking_get_next_studygroup($type, $studygroups) {
$count = count($studygroups) - 1;
for ($i = 0; $i < $count; $i++)
{
for ($i = 0; $i < $count; $i++) {
$group = $studygroups[$i];
$leader = $group->leader_nid;
//watchdog('booking_debug', "<pre>Study Group Element at index $i:\n@info</pre>", array('@info' => print_r( $group, true)));
//watchdog('booking_debug', "<pre>Study Group Leader NID at index $i:\n@info</pre>", array('@info' => var_dump($group)));
if ($leader == 0)
{
if ($leader == 0) {
return $i;
}
}
}
/**
@@ -101,9 +95,7 @@ function _booking_studygroups_retrieve_eligible_people() {
$bookedin_result = $query->execute();
//iterate over the attendee associative array and add some fields
foreach ($bookedin_result as $person)
{
foreach ($bookedin_result as $person) {
$person->processed = 0;
$person->leading = array();
$person->helping = array();
@@ -116,7 +108,7 @@ function _booking_studygroups_retrieve_eligible_people() {
FROM (
SELECT p.nid, p.booking_firstname, p.booking_lastname, p.booking_state, p.booking_country, p.booking_readinggroup, pay.booking_payment_date, p.booking_status, p.booking_gender, p.booking_dob
FROM {booking_person} p, {booking_payment} pay
WHERE booking_eventid = :eid and p.nid = pay.booking_person_nid and ( booking_status = 2 or booking_status = 4)
WHERE p.booking_eventid = :eid and p.nid = pay.booking_person_nid and ( p.booking_status = 2 or p.booking_status = 4)
LIMIT 100
) AS booking
WHERE booking_gender = \'M\'
@@ -124,9 +116,7 @@ function _booking_studygroups_retrieve_eligible_people() {
array(':eid' => $event->eid));
//iterate over the attendee associative array and add some fields
foreach ($result2 as $person)
{
foreach ($result2 as $person){
$person->processed = 0;
$person->leading = array();
$person->helping = array();
@@ -140,8 +130,6 @@ function _booking_studygroups_retrieve_eligible_people() {
}
/**
* Function for
*/
@@ -158,11 +146,9 @@ function _booking_studygroups_retrieve_groups() {
//assume they all have the same number of sessions
//$num_sessions = $studygroup->booking_num_group_sessions;
foreach ($group_mapping as $group)
{
foreach ($group_mapping as $group) {
//watchdog('booking_debug', "<pre>Study Group Element:\n@info</pre>", array('@info' => print_r( $group, true)));
for ($i = 1; $i <= 16; $i++)
{
for ($i = 1; $i <= 16; $i++) {
$new_group = clone $group;
$new_group->session_id = $i;
@@ -179,3 +165,337 @@ function _booking_studygroups_retrieve_groups() {
return $groups;
}
/**
* autocomplete helper to look up names for room allocations
* based on https://www.drupal.org/node/854216
* $string = string for search
*/
function _booking_studygroups_name_autocomplete($string) {
global $event;
$matches = array();
$query = db_select('booking_person', 'p')
->fields('p', array('nid', 'booking_firstname', 'booking_lastname'));
$db_or = db_or()
->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE')
->condition('p.nid', $string, "=");
$db_and = db_and()->condition($db_or)->condition('p.booking_eventid', $event->eid, '=');
$result = $query->condition($db_and)
->execute();
// save the query to matches
foreach ($result as $row) {
$name = $row->booking_lastname . ', ' . $row->booking_firstname . ' [' . $row->nid . ']';
$matches[$name] = $name;
}
// Return the result to the form in json
drupal_json_output($matches);
}
/**
* Function to allow admin to edit leaders and helpers for a study group
* Not sure where the original idea came from but https://knackforge.com/blog/selvam/drupal-7-creating-editable-table-form-api is similar
*/
function booking_studygroup_leadhelp_edit_form($node, &$form_state, $group_id) {
global $event;
//verify that $group_id is a number
if (! preg_match('/^[0-9]+$/', $group_id)) {
drupal_set_message("Error: Invalid study group ID '" . $group_id . "' supplied. Unable to edit group leaders and helpers.", 'error', FALSE);
drupal_goto('admin/booking/studygroups');
return "";
}
//try to select the study group for this $group_id
$studygroup = db_query("SELECT * FROM {booking_studygroup_list} WHERE sid = :sid", array(':sid' => $group_id))
->fetchObject();
if (! $studygroup) {
drupal_set_message("Error: Could not find matching study group ID. Unable to edit leaders/helpers.", 'error', FALSE);
drupal_goto('admin/booking/studygroups');
return "";
}
//define the table header
$header = array (
'sid' => array('data' => t('Study Group Session ID'), 'field' => 'sid'),
'booking_assign_leader' => array('data' => t('Leader')),
'booking_assign_helper' => array('data' => t('Helper')),
'booking_assign_reserveleader' => array('data' => t('Reserve Leader')),
'booking_assign_reservehelper' => array('data' => t('Reserve Helper')),
);
//attach the custom css
$form['#attached']['css'] = array(
drupal_get_path('module', 'booking') . '/booking.css',
);
$prefix = t("<h2>Edit Leaders/Helpers for Study Group &dash; !descrip</h2>",
array('!descrip' => $studygroup->booking_studygroup_descrip));
$prefix .= "<p>Enter part of a person's name in the text field and wait for the blue spinning circle to autocomplete with the person's details. " .
"Make sure you click on the person from the dropdown list that appears.</p>";
$form['first_para'] = array (
'#type' => 'markup',
'#markup' => $prefix,
);
//add this to the form in a hidden field so we can update the right studygroup
$form['booking_gid'] = array (
'#type' => 'hidden',
'#value' => $group_id,
);
//create the container element for the whole table
$form['studygroups'] = array(
'#prefix' => '<div id="studygroups">',
'#suffix' => '</div>',
'#tree' => TRUE,
'#theme' => 'table',
'#header' => $header,
'#rows' => array(),
);
//get the list of study group session memberships
$session_members_query = db_query("SELECT m.*, p.* FROM {booking_studygroup_mapping} m
inner join {booking_person} p on p.nid = m.booking_node_id
WHERE m.booking_studygroup_id = :gid AND m.booking_studygroup_role > 0",
array(':gid' => $group_id));
$session_members = $session_members_query->fetchAllAssoc('booking_node_id');
//create an array representing the existing leaders/helpers for this group
$existing_leaders = array();
foreach ($session_members as $person) {
$existing_leaders[$person->booking_session_id][$person->booking_studygroup_role] =
$person->booking_lastname . ', ' . $person->booking_firstname . ' [' . $person->booking_node_id . ']';
}
//create the rows for the individual sessions (instances really) of this study group
for ($i = 1; $i <= $studygroup->booking_num_group_sessions; $i++) {
$leader = array (
'#id' => 'booking-studygroup-leader-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_leader[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][1])) ? $existing_leaders[$i][1] : '',
'#attributes' => array('style' => array('width:200px')),
);
$helper = array (
'#id' => 'booking-studygroup-helper-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_helper[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][2])) ? $existing_leaders[$i][2] : '',
'#attributes' => array('style' => array('width:200px')),
);
$reserveleader = array (
'#id' => 'booking-studygroup-reserveleader-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_reserveleader[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][3])) ? $existing_leaders[$i][3] : '',
'#attributes' => array('style' => array('width:200px')),
);
$reservehelper = array (
'#id' => 'booking-studygroup-reservehelper-' . $i,
'#type' => 'textfield',
'#title' => 'Name',
'#title_display' => 'invisible',
'#name' => 'booking_studygroup_reservehelper[' . $i . ']',
'#size' => 100,
'#autocomplete_path' => 'booking/studygroups/autocomplete',
'#value' => (!empty($existing_leaders[$i][4])) ? $existing_leaders[$i][4] : '',
'#attributes' => array('style' => array('width:200px')),
);
$form['studygroups'][$i] = array(
'booking-studygroup-leader' => &$leader,
'booking-studygroup-helper' => &$helper,
'booking-studygroup-reserveleader' => &$reserveleader,
'booking-studygroup-reservehelper' => &$reservehelper,
);
$new_row = array();
//handle readings group differently
if ($studygroup->booking_is_readinggroup == 'Y') {
$new_row['sid'] = _booking_readinggroup_colour_lookup($i);
}
//non readings groups just show the session ID
else {
$new_row['sid'] = $i;
}
$new_row['booking_studygroup_leader'] = array('data' => &$leader);
$new_row['booking_studygroup_helper'] = array('data' => &$helper);
$new_row['booking_studygroup_reserveleader'] = array('data' => &$reserveleader);
$new_row['booking_studygroup_reservehelper'] = array('data' => &$reservehelper);
$form['studygroups']['#rows'][$i] = $new_row;
//clean up references
unset($leader);
unset($helper);
unset($reserveleader);
unset($reservehelper);
}
//record whether this was a reading group, so we can update colours if necessary
$form['booking_readinggroup'] = array (
'#type' => 'hidden',
'#value' => $studygroup->booking_is_readinggroup,
);
//close out the form
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Submit'),
);
return array (
'form' => $form,
);
}
/**
* Process the submission for leaders/helpers
*/
function booking_studygroup_leadhelp_edit_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
$group_id = $form_state['values']['booking_gid'];
$update_messages = array();
$counter = 0;
//watchdog('booking_debug', "<pre>Studygroup leader/helper test submission form :\n@info</pre>", array('@info' => print_r( $form_state, true)));
$role_types = array(
'booking_studygroup_leader' => 1,
'booking_studygroup_helper' => 2,
'booking_studygroup_reserveleader' => 3,
'booking_studygroup_reservehelper' => 4,
);
//iterate over the different role types
foreach ($role_types as $type => $type_id) {
//iterate over the sessions for that role type
foreach ($values[$type] as $session_id => $person) {
//get the previous value
$previous_value = _booking_studygroup_leadhelp_edit_get_previous_value($form, $type, $type . '[' . $session_id . ']');
//watchdog('booking_debug', "<pre>Studygroup assignment previous value:\n@info\nCurrent value:\n@current</pre>",
// array('@info' => print_r( $previous_value, true), '@current' => print_r( $person, true)));
//compare it against $person
//if $person is now empty, set the person's role to zero
if (empty($person) && $previous_value != 0) {
$update_messages[] = t("Clearing leader/helper role for nid @id and session @session in group @group. Used to have role @role.",
array('@id' => $previous_value, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => 0,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $previous_value)
->condition('booking_session_id', $session_id)
->execute();
$counter++;
}
elseif (!empty($person)) {
preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches);
$person_nid = $matches[1];
//if $person is now different, run an update query
if ($person_nid != $previous_value) {
//check if this person is already a member of this studygroup
$group_query = db_query("SELECT * FROM {booking_studygroup_mapping} " .
"WHERE booking_eventid = :eid AND booking_node_id = :nid AND booking_studygroup_id = :gid",
array(':eid' => $event->eid, ':nid' => $person_nid, ':gid' => $group_id))
->fetchObject();
if (! $group_query) {
//this person doesn't seem to already be in this study group so insert a record
$update_messages[] = t("Adding via insert: role @role to nid @id in group @group and session @session.",
array('@id' => $person_nid, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_insert('booking_studygroup_mapping')
->fields(array(
'booking_eventid' => $event->eid,
'booking_node_id' => $person_nid,
'booking_studygroup_id' => $group_id,
'booking_session_id' => $session_id,
'booking_studygroup_role' => $type_id,
))
->execute();
}
else {
//update the role for the new person
$update_messages[] = t("Adding via update: role @role to nid @id in group @group and session @session.",
array('@id' => $person_nid, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => $type_id,
'booking_session_id' => $session_id,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $person_nid)
->execute();
}
$counter++;
//remove the role from the old person if there was someone else there before
if ($previous_value != 0) {
$update_messages[] = t("Removing role @role from nid @id in group @group and session @session.",
array('@id' => $previous_value, '@group' => $group_id, '@role' => $type_id, '@session' => $session_id));
db_update('booking_studygroup_mapping')
->fields(array(
'booking_studygroup_role' => 0,
))
->condition('booking_studygroup_id', $group_id)
->condition('booking_node_id', $previous_value)
->condition('booking_session_id', $session_id)
->execute();
$counter++;
} //end previous value check
} //end different person check
} //end empty person check
} //iterate session
} //iterate role type
//do we need to update colours for reading group?
if ($form_state['values']['booking_readinggroup'] == 'Y') {
booking_studygroups_process_colours();
}
$final_message = "Made $counter update(s) to leader/helper roles for study group id $group_id. Changing one person to another counts as two updates.";
drupal_set_message($final_message, 'status', FALSE);
watchdog('booking', "<pre>" . $final_message . "\n" . implode("\n", $update_messages) . "</pre>");
}
/**
* look through the previous form data and return the matching element
*/
function _booking_studygroup_leadhelp_edit_get_previous_value(&$form, $type, $name) {
foreach($form['form']['studygroups']['#rows'] as $key => $value) {
//watchdog('booking_debug', "<pre>Studygroup assignment checker for type !type in session !name:\n@info</pre>",
// array('!session' => $name, '!type' => $type, '@info' => print_r( $value, true)));
//return;
if ((!empty($value[$type]['data']['#value'])) && ($value[$type]['data']['#name'] == $name)) {
//found the correct element, extract the node id
$person = $value[$type]['data']['#value'];
if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) {
return $matches[1];
}
}
}
//in case there was no matching value, return an empty string
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,13 +7,13 @@
/**
* Function for listing the study groups and the ability to edit the group definitions
* Function for admin page listing the study groups and the ability to edit the group definitions
*/
function booking_studygroups_admin() {
global $event;
$output = "";
$header = array('Study Group', 'Session Count', 'Reading Group?', 'Edit Definition');
$header = array('Study Group Day', 'Study Group Title', 'Study Group Explanation', 'Session Count', 'Reading Group?', 'Edit Definition');
$rows = array();
$attributes = array('style' => 'max-width:60%');
//$attributes = array();
@@ -26,7 +26,9 @@ function booking_studygroups_admin() {
foreach ($result as $group) {
$rows[] = array(
$group->booking_studygroup_weekday,
$group->booking_studygroup_descrip,
$group->booking_studygroup_explanation,
$group->booking_num_group_sessions,
$group->booking_is_readinggroup == 'Y' ? 'Yes' : 'No',
l(t('Edit Group Definition', array('!id' => $group->sid)), t('admin/config/booking/studygroups/!id/edit', array('!id' => $group->sid))),
@@ -38,7 +40,6 @@ function booking_studygroups_admin() {
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes));
return $output;
}
/**
@@ -48,7 +49,9 @@ function booking_studygroups_view_summary() {
global $event;
$output = "";
$header = array('Study Group', 'Session Count', 'Reading Group?', 'View Membership', 'Compute Membership', 'Select Leaders', 'Download CSV');
$header = array('Study Group Day', 'Study Group Title',
'Session Count', 'Reading Group?', 'View Membership', 'Compute Membership',
'Select Leaders', 'Download CSV');
//$attributes = array('style' => 'max-width:50%');
$attributes = array();
$rows = array();
@@ -61,12 +64,13 @@ function booking_studygroups_view_summary() {
foreach ($result as $group) {
$rows[] = array(
$group->booking_studygroup_weekday,
$group->booking_studygroup_descrip,
$group->booking_num_group_sessions,
$group->booking_is_readinggroup == 'Y' ? 'Yes' : 'No',
l(t('Current Membership', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/view', array('!id' => $group->sid))),
l(t('Compute Membership Update', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/update', array('!id' => $group->sid))),
l(t('Edit Leaders/Helpers', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/selectleaders', array('!id' => $group->sid))),
l(t('Edit Leaders/Helpers', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/editleaders', array('!id' => $group->sid))),
l(t('Download', array('!id' => $group->sid)), t('admin/booking/studygroups/!id/view/csv', array('!id' => $group->sid))),
);
}
@@ -87,14 +91,12 @@ function booking_studygroups_define_form($node, &$form_state, $create, $editid =
$form = array();
$prefix = "<p>Add a new study group definition</p>";
if ($create == true)
{
if ($create == true) {
drupal_set_title('Add Study Group');
$data = $node;
watchdog('booking', 'Creating new study group: @info', array ('@info' => var_export($node, TRUE)));
watchdog('booking_debug', 'Creating new study group: @info', array ('@info' => var_export($form_state, TRUE)));
}
else
{
else {
drupal_set_title('Edit Study Group');
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $editid)) {
@@ -104,29 +106,44 @@ function booking_studygroups_define_form($node, &$form_state, $create, $editid =
}
$data = db_query("SELECT * FROM {booking_studygroup_list} WHERE sid = :id",
array(':id' => $editid))
->fetchObject();
array(':id' => $editid))->fetchObject();
$prefix = t("<p>Update the &quot;!event &quot; study group definition.</p>", array('!event' => $data->booking_studygroup_descrip));
//add this to the form in a hidden field so we can update the right price
$form['booking_sid'] = array (
'#type' => 'hidden',
'#value' => $editid,
);
watchdog('booking', 'Editing study group definition: @info',
array ('@info' => var_export($data, TRUE)));
watchdog('booking_debug', "<pre>Editing study group definition:\n@info</pre>", array ('@info' => print_r($data, TRUE)));
}
if(!isset($form_state['storage']['confirm']))
{
if(!isset($form_state['storage']['confirm'])) {
$form['booking_studygroup_weekday'] = array (
'#type' => 'textfield',
'#title' => t('Day of the week this study group will be held'),
'#description' => t('For example, "Monday"'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_studygroup_weekday) ? $data->booking_studygroup_weekday : '',
);
$form['booking_studygroup_descrip'] = array (
'#type' => 'textfield',
'#title' => t('Description of this study group (eg Monday)'),
'#title' => t('Description of this study group'),
'#description' => t('For example, "Study Group 1"'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_studygroup_descrip) ? $data->booking_studygroup_descrip : '',
);
$form['booking_studygroup_explanation'] = array (
'#type' => 'textfield',
'#title' => t('Explanation for this study group'),
'#description' => t('For example, "This relates to section 1 of the notes, which covers Matthew chapter 1."'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_studygroup_explanation) ? $data->booking_studygroup_explanation : '',
);
$form['booking_num_group_sessions'] = array (
'#type' => 'textfield',
@@ -144,15 +161,15 @@ function booking_studygroups_define_form($node, &$form_state, $create, $editid =
'#options' => array (0 => t('No'), t('Yes')),
'#default_value' => !empty($data->booking_is_readinggroup) ? ($data->booking_is_readinggroup == 'Y' ? 1 : 0) : 0,
);
if ($create == true)
{
//create the buttons
if ($create == true) {
$form['submit'] = array
(
'#type' => 'submit',
'#value' => t('Create Study Group'),
);
} else {
}
else {
$form['Update'] = array
(
'#type' => 'submit',
@@ -164,7 +181,7 @@ function booking_studygroups_define_form($node, &$form_state, $create, $editid =
'#value' => t("Delete Study Group Definition"),
);
}
//return the render array
return array (
'first_para' => array (
'#type' => 'markup',
@@ -174,15 +191,16 @@ function booking_studygroups_define_form($node, &$form_state, $create, $editid =
);
}
//confirm delete
else
{
else {
return confirm_form($form, "Are you sure you wish to delete studygroup definition with id " . $editid . "?",
current_path(), NULL, "Delete Study Group Definition");
}
}
/**
* Process addition/update/delete of a studygroup definition
*/
function booking_studygroups_define_form_submit($form, &$form_state) {
global $event;
@@ -195,12 +213,13 @@ function booking_studygroups_define_form_submit($form, &$form_state) {
array(':eid' => $event->eid))->fetchObject();
//watchdog('booking', 'Checkboxes when setting buttons: @info', array ('@info' => var_export($checkboxes, TRUE)));
if ($form_state['values']['op'] == 'Create Study Group')
{
if ($form_state['values']['op'] == 'Create Study Group') {
db_insert('booking_studygroup_list')
->fields(array(
'booking_eventid' => $event->eid,
'booking_studygroup_weekday' => $values['booking_studygroup_weekday'],
'booking_studygroup_descrip' => $values['booking_studygroup_descrip'],
'booking_studygroup_explanation' => $values['booking_studygroup_explanation'],
'booking_num_group_sessions' => $values['booking_num_group_sessions'],
'booking_is_readinggroup' => $values['booking_is_readinggroup'] == 1 ? 'Y' : 'N',
))
@@ -209,33 +228,27 @@ function booking_studygroups_define_form_submit($form, &$form_state) {
$new_count = $count->num + 1;
}
//if we're deleting, add the confirmation to the form if it hasn't been defined yet
elseif($form_state['values']['op'] == "Delete Study Group Definition" && (!isset($form_state['storage']['confirm'])))
{
elseif($form_state['values']['op'] == "Delete Study Group Definition" && (!isset($form_state['storage']['confirm']))) {
watchdog('booking', "<pre>Studygroup deletion confirmation being set:\n@info</pre>", array('@info' => print_r( $form_state, true)));
$form_state['storage']['confirm'] = TRUE;
$form_state['rebuild'] = TRUE;
$new_count = $count->num;
}
elseif ($form_state['values']['op'] == 'Delete Study Group Definition')
{
elseif ($form_state['values']['op'] == 'Delete Study Group Definition') {
//verify that booking_pid is a number
if (! preg_match('/^[0-9]+$/', $values['booking_sid'])) {
drupal_set_message("Error: Invalid studygroup ID supplied. Unable to delete entry.", 'error', FALSE);
return "";
}
//TODO: Confirmation
//return confirm_form($form, "Really delete price?", 'admin/config/booking/prices');
$num_deleted = db_delete('booking_studygroup_list')
->condition('sid', $values['booking_sid'])
->execute();
$new_count = $count->num - 1;
}
elseif ($form_state['values']['op'] == 'Update Study Group')
{
elseif ($form_state['values']['op'] == 'Update Study Group') {
//verify that booking_sid is a number
if (! preg_match('/^[0-9]+$/', $values['booking_sid'])) {
@@ -247,7 +260,9 @@ function booking_studygroups_define_form_submit($form, &$form_state) {
db_update('booking_studygroup_list')
->fields(array (
'booking_eventid' => $event->eid,
'booking_studygroup_weekday' => $values['booking_studygroup_weekday'],
'booking_studygroup_descrip' => $values['booking_studygroup_descrip'],
'booking_studygroup_explanation' => $values['booking_studygroup_explanation'],
'booking_num_group_sessions' => $values['booking_num_group_sessions'],
'booking_is_readinggroup' => $values['booking_is_readinggroup'] == 1 ? 'Y' : 'N',
))
@@ -259,6 +274,8 @@ function booking_studygroups_define_form_submit($form, &$form_state) {
//update the number of study groups now defined
variable_set('booking_studygroup_count', $new_count);
//call the mysql view update function so that the view matches the new number of study groups
_booking_node_create_mysqlview();
//redirect to the specified path now that the form has been processed
$form_state['redirect'] = $redirect_path;
}

View File

@@ -19,8 +19,7 @@ function booking_studygroups_csv_report($group_id) {
array(':eid' => $event->eid, ':sid' => $group_id))
->fetchObject();
if (! $group)
{
if (! $group) {
drupal_set_message("Error: Could not find matching study group ID. Unable to view group membership.", 'error', FALSE);
drupal_goto('admin/booking/studygroups');
return "";
@@ -38,26 +37,41 @@ function booking_studygroups_csv_report($group_id) {
$enclosure_esc = preg_quote($enclosure, '/');
//get the list of study group session memberships
$session_members_query = db_query("SELECT m.*, p.booking_firstname, p.booking_lastname FROM {booking_studygroup_mapping} m
$session_members_query = db_query("SELECT m.*, p.* FROM {booking_studygroup_mapping} m
inner join {booking_person} p on p.nid = m.booking_node_id
WHERE m.booking_studygroup_id = :sid ORDER BY m.booking_session_id, m.booking_studygroup_role DESC",
WHERE m.booking_studygroup_id = :sid ORDER BY m.booking_session_id, m.booking_studygroup_role DESC, p.booking_lastname",
array(':sid' => $group_id));
$session_members = $session_members_query->fetchAll();
// Check if we had no data added, that means there were no people in this study group
if (! $session_members) {
drupal_set_message("Error: Study group $group_id has no members assigned.", 'error', FALSE);
drupal_goto('admin/booking/studygroups');
return "";
}
//generate the row data
foreach ($session_members as $member) {
if (! isset($data[$member->booking_session_id])) {
$data[$member->booking_session_id] = array();
}
// lookup the name and role for this entry in the study group session
// lookup the name and role for this entry in the study group session and optionally include age
if (variable_get('booking_studygroup_csv_ages', 0) == 1) {
$text = array($member->booking_firstname, $member->booking_lastname, '[' . _booking_get_age_years($member->booking_dob) .']');
}
else {
$text = array($member->booking_firstname, $member->booking_lastname);
}
//add their role if they're leading/helping etc
if ($member->booking_studygroup_role > 0) {
array_push($text, '(' . _booking_studygroup_role_lookup($member->booking_studygroup_role) . ')');
}
//also tag committee members
if ($member->booking_committee_member == 'Y') {
array_push($text, '(committee)');
}
//add the spaces and put this element in the right array
$data[$member->booking_session_id][] = implode(' ', $text);
}
//watchdog('booking_debug', "<pre>Study Group CSV Report\n@info</pre>", array('@info' => print_r( $data_array, true)));
@@ -68,8 +82,13 @@ function booking_studygroups_csv_report($group_id) {
foreach ($header_array as $column) {
$maximums[] = count($data[$column]);
//make the column headings a bit more user friendly
if ($group->booking_is_readinggroup == 'Y') {
$column_headings[] = _booking_readinggroup_colour_lookup($column);
}
else {
$column_headings[] = "Session " . $column;
}
}
//add the column headings to the CSV
$header = implode( $delimiter, $column_headings );
@@ -100,3 +119,59 @@ function booking_studygroups_csv_report($group_id) {
print $csv;
exit(0);
}
/**
* Function to generate table listing all males and groups they're leading/helping
*/
function booking_studygroups_leadhelp_view_summary() {
global $event;
$output = "";
$header = array('First Name', 'Last Name');
$rows = array();
$attributes = array('style' => 'max-width:100%');
//get study group definitions
$query = db_select('booking_studygroup_list', 's')
->fields('s')
->condition('s.booking_eventid', $event->eid, '=')
->orderBy('sid');
$studygroup_list = $query->execute()->fetchAllAssoc('sid');
//add columns for the study groups
foreach ($studygroup_list as $group) {
$header[] = $group->booking_studygroup_descrip;
}
$person_query = db_query("SELECT * FROM {booking_person_view} WHERE booking_gender = 'M' " .
" AND (booking_status = 1 OR booking_status = 2)" .
" ORDER BY booking_lastname, booking_firstname")->fetchAllAssoc('nid');
//loop through each matching person
foreach ($person_query as $person) {
//add the name to an array for this line
$newline = array($person->booking_firstname, $person->booking_lastname);
foreach ($studygroup_list as $group) {
$session = 'session' . $group->sid;
$session_role = 'session' . $group->sid . '_role';
//add details if they have a role for this studygroup
if ($person->$session_role > 0) {
$text = _booking_studygroup_role_lookup($person->$session_role);
$newline[] .= "<b>" . $text . "</b>, session #" . $person->$session;
}
//otherwise put a blank entry for this studygroup
else {
$newline[] = "";
}
} //end iterate studygroup list
//add the line to the array of rows
$rows[] = $newline;
} //end iterate person list
//output everything
$output .= t("<h3>!event Study Group Leaders and Helpers</h3>", array('!event' => $event->booking_eventname));
$output .= t("<p>This page lists all males that are either booked in or on the waiting list.</p>");
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes));
return $output;
}

View File

@@ -1,5 +1,4 @@
<?php
// $Id: booking.admin.inc,v 0.1 2011/07/12
/**
* @file
@@ -48,49 +47,6 @@ function booking_tokens_admin() {
$booking_waitingpage_pre_nowaitlist_text = "<p>There's no one on the waiting list yet. If you haven't already done so, go ahead and <a href=\"/booking\">register</a>.</p>\n<br />\n";
$booking_waitingpage_post_text = "<p></p>\n";
$default_email_text = "Dear [booking:fname],\n" .
"Congratulations, you are officially booked into [booking:eventname]. " .
"Your registration reference number is [booking:booking-id].\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. " .
"We look forward to seeing you (God Willing) at [booking:eventname]!\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_regn_complete_text = "Dear [booking:fname],\n" .
"Thank-you for completing your payment for [booking:eventname].\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. " .
"We look forward to seeing you (God Willing) at [booking:eventname]!\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_waitinglist_text = "Dear [booking:fname],\n" .
"Thank-you for registering to attend [booking:eventname]. Unfortunately the venue for this event is full, and you have been placed on the waiting list to attend.\n" .
"We will contact you if a position becomes available for you. Please don't hesitate to contact us if you have any queries by replying to this email.\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n" .
"The following information shows the details you entered when you registered. " .
"If any of this information is incorrect, please reply to this email with the corrections as soon as possible.\n" .
"________________________________________________________";
$booking_email_paymentoutstanding_text = "Dear [booking:fname],\n" .
"Thank-you for registering to attend [booking:eventname]. Our records indicate that you currently have $[booking:payment-required] outstanding to finalise your registration.\n" .
"Please visit [booking:balance-payment-link] in order to make your final payment.\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team\n" .
"________________________________________________________\n";
$booking_email_waitinglistpromotion = "Dear [booking:fname],\n" .
"We have some great news for you. A place at [booking:eventname] for you has just become available. " .
"If you wish to secure your place at [booking:eventname], please visit [booking:balance-payment-link] to make your final payment. " .
"Our records indicate that you currently have $[booking:paypal-total-amount] outstanding (including Paypal transaction fees).\n" .
"Once we have received your payment, you will be sent an automatic confirmation email thanking you for paying your outstanding fees. " .
"If you are paying via Paypal's eCheque feature, please be aware that payments take 3-5 working days to clear, " .
"and you will not receive the confirmation email until that has occurred.\n" .
"Please don't hesitate to contact us if you have any queries by replying to this email. We look forward to seeing you, God Willing, at [booking:eventname]\n" .
"Love in Jesus,\n[booking:eventname] Registrations Team.";
$booking_email_notcoming_demotion = "";
$booking_email_paymentoutstanding_married_text = "";
$booking_confirmation_text = "<p>Thanks for filling out the registration form.</p>\n" .
"<p>To complete your booking, please make a payment of <strong>$[booking:payment-required]</strong> into the following bank account<br />\n" .
"&nbsp;Account Name: blah<br />\n&nbsp;BSB: blah<br />\n&nbsp;Account Number: blah</p>\n" .
@@ -193,17 +149,7 @@ $booking_registration_intro_text = variable_get('booking_registration_intro_text
'#description' => t(''),
'#default_value' => variable_get('booking_regn_confirm_married_text', $booking_regn_confirm_married_text),
);
//$booking_regn_completed_page_default = variable_get('booking_regn_completed_page');
//$booking_regn_completed_page = isset($booking_regn_completed_page_default['value']) ? $booking_regn_completed_page_default['value'] : '';
$form['confirmation']['booking_regn_completed_page'] = array(
'#title' => t('Text to use for landing page on return from paypal website'),
'#type' => 'textarea',
'#description' => t(''),
//'#default_value' => $booking_regn_completed_page,
'#default_value' => isset(variable_get('booking_regn_completed_page')['value']) ? variable_get('booking_regn_completed_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
/*Text for the balance payment page*/
$form['balance'] = array(
'#type' => 'fieldset',
@@ -311,6 +257,40 @@ $booking_registration_intro_text = variable_get('booking_registration_intro_text
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['travel']['booking_travelform_page'] = array(
'#title' => t('Text to use at the start of the travel form for a non-married person.'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => isset(variable_get('booking_travelform_page')['value']) ? variable_get('booking_travelform_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
$form['travel']['booking_travelform_married_page'] = array(
'#title' => t('Text to use at the start of the travel form for a married couple. Only applies if combined pricing is enabled.'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => isset(variable_get('booking_travelform_married_page')['value']) ? variable_get('booking_travelform_married_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
$form['travel']['booking_travelform_page_post_text'] = array(
'#title' => t('Text to use at the end of the travel form. This is not displayed on the "travel form completed" page defined below.'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => isset(variable_get('booking_travelform_page_post_text')['value']) ? variable_get('booking_travelform_page_post_text')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
$form['travel']['booking_travelform_completed_page'] = array(
'#title' => t('Text to use on the travel form if the form has already been submitted.'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => isset(variable_get('booking_travelform_completed_page')['value']) ? variable_get('booking_travelform_completed_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
/*
$form['travel']['booking_travelform_page'] = array(
'#title' => t('Text to use at the start of the travel form for a non-married person.'),
'#type' => 'textarea',
@@ -329,165 +309,36 @@ $booking_registration_intro_text = variable_get('booking_registration_intro_text
'#description' => t(''),
'#default_value' => variable_get('booking_travelform_completed_page', ''),
);
*/
/*Text for emails*/
$form['emails'] = array(
//other pages like paypal landing page
$form['otherpages'] = array(
'#type' => 'fieldset',
'#title' => 'Built-In Workflow Email Definitions',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['emails']['booking_email_notification_text'] = array(
'#title' => t('Notification Email'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#description' => t('Email to send to the notification email address (defined in general configuration) when a person has registered'),
'#default_value' => variable_get('booking_email_notification_text', '[booking:regn-summary]'),
);
$form['emails']['booking_email_bookedin_text'] = array(
'#title' => t('Registration Successful Email'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#description' => t('Text to use in an email indicating the person has booked in, paid their deposit and is not on the waiting list'),
'#default_value' => variable_get('booking_email_bookedin_text', $default_email_text),
);
$form['emails']['booking_email_regn_complete_text'] = array(
'#title' => t('Payment Complete Email'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#description' => t('Email text to indicate a person has booked in, fully paid and is not on the waiting list. ' .
'This will be sent either at initial registration if the full amount is paid, or when the balance is paid.'),
'#default_value' => variable_get('booking_email_regn_complete_text', $booking_email_regn_complete_text),
);
$form['emails']['booking_email_waitinglist_text'] = array(
'#title' => t('Registration on Waiting List Email'),
'#description' => t('Email text to indicate a person has registered but is on the waiting list. ' .
'This will be sent instead of the Registration Successful or Registration Complete emails if the person is on the waiting list.'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#default_value' => variable_get('booking_email_waitinglist_text', $booking_email_waitinglist_text),
);
$form['emails']['booking_email_partialpayment_received_text'] = array(
'#title' => t('Email text to send a person thanking them for their partial payment'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#description' => t(''),
'#default_value' => variable_get('booking_email_partialpayment_received_text', ''),
);
$form['emails']['booking_email_paymentoutstanding_subject'] = array (
'#type' => 'textfield',
'#title' => t('Balance Outstanding Email Subject'),
'#description' => t('Subject line for email advising attendee they missed the payment deadline'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_paymentoutstanding_subject','[booking:eventname] payment required'),
);
$form['emails']['booking_email_paymentoutstanding_text'] = array(
'#description' => t('Email text to send a person reminding them of how much they owe'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#title' => t('Balance Outstanding Email Text'),
'#default_value' => variable_get('booking_email_paymentoutstanding_text', $booking_email_paymentoutstanding_text),
);
$form['emails']['booking_email_paymentoutstanding_married_text'] = array(
'#title' => t('Email text to send a married couple reminding them of how much they both owe (only applies when combined pricing enabled)'),
'#type' => 'textarea',
//'#format' => 'full_html',
'#description' => t(''),
'#default_value' => variable_get('booking_email_paymentoutstanding_married_text', $booking_email_paymentoutstanding_married_text),
);
$form['emails']['booking_email_waitinglistpromotion'] = array(
'#title' => t('Email text to send a person on the waiting list when a spot opens up for them'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => variable_get('booking_email_waitinglistpromotion', $booking_email_waitinglistpromotion),
);
$form['emails']['booking_email_notcoming_demotion_subject'] = array (
'#type' => 'textfield',
'#title' => t('Withdrawal Processed Email'),
'#description' => t('Subject line for email advising attendee their withdrawal has been processed'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_notcoming_demotion_subject','[booking:eventname] withdrawal processed'),
);
$form['emails']['booking_email_notcoming_demotion'] = array(
'#title' => t('Email text to send a person who withdraws their registration'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => variable_get('booking_email_notcoming_demotion', $booking_email_notcoming_demotion),
);
$form['emails']['booking_email_missedpayment_subject'] = array (
'#type' => 'textfield',
'#title' => t('Missed Payment Email Subject'),
'#description' => t('Subject line for email advising attendee they missed the payment deadline'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_missedpayment_subject','[booking:eventname] payment deadline missed'),
);
$form['emails']['booking_email_missedpayment'] = array(
'#title' => t('Missed Payment Email Text'),
'#type' => 'textarea',
'#description' => t('Email text to send a person who missed the payment deadline'),
'#default_value' => variable_get('booking_email_missedpayment', ''),
);
$form['emails']['booking_email_travel_required_subject'] = array (
'#type' => 'textfield',
'#title' => t('Travel Form Required Subject'),
'#description' => t('Subject line for email requesting attendee to complete the travel form'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_travel_required_subject','[booking:eventname] Travel Details Required'),
);
$form['emails']['booking_email_travel_required_text'] = array(
'#title' => t('Travel Form Required Text'),
'#description' => t('Email text requesting attendee to complete the travel form. This email will be sent from the !email email address', array('!email' => variable_get('booking_logistics_email'))),
'#type' => 'textarea',
'#default_value' => variable_get('booking_email_travel_required_text', ''),
);
$form['emails']['booking_email_travel_complete_subject'] = array (
'#type' => 'textfield',
'#title' => t('Travel Form Complete Subject'),
'#description' => t('Subject line for email indicating a person has completed the travel form'),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get('booking_email_travel_complete_subject','[booking:eventname] Travel Details Received'),
);
$form['emails']['booking_email_travel_complete_text'] = array(
'#title' => t('Travel Form Complete Text'),
'#description' => t('Email text to indicate a person has completed the travel form. This email will be sent from the !email email address', array('!email' => variable_get('booking_logistics_email'))),
'#type' => 'textarea',
'#default_value' => variable_get('booking_email_travel_complete_text', ''),
);
/*Text for emails*/
$form['custom-emails'] = array(
'#type' => 'fieldset',
'#title' => 'Custom Email Text Definitions',
'#title' => 'Miscellaneous pages',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
//add a bunch of custom emails
for ($i = 1; $i <= variable_get('booking_custom_email_count','5'); $i++)
{
$subject_fieldname = 'booking_email_subject_custom' . $i;
$body_fieldname = 'booking_email_custom' . $i;
$form['custom-emails'][$subject_fieldname] = array (
'#type' => 'textfield',
'#title' => t('Subject line for Custom Email ' . $i),
'#size' => 150,
'#maxlength' => 300,
'#default_value' => variable_get($subject_fieldname,'[booking:eventname]'),
);
$form['custom-emails'][$body_fieldname] = array(
'#title' => t('Email text for custom email ' . $i),
//$booking_regn_completed_page_default = variable_get('booking_regn_completed_page');
//$booking_regn_completed_page = isset($booking_regn_completed_page_default['value']) ? $booking_regn_completed_page_default['value'] : '';
$form['otherpages']['booking_regn_completed_page'] = array(
'#title' => t('Text to use for landing page on return from paypal website'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => variable_get($body_fieldname, ''),
//'#default_value' => $booking_regn_completed_page,
'#default_value' => isset(variable_get('booking_regn_completed_page')['value']) ? variable_get('booking_regn_completed_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
}
$form['otherpages']['booking_variety_regn_page'] = array(
'#title' => t('Text to use at the start of the variety session registration form'),
'#type' => 'textarea',
'#description' => t(''),
'#default_value' => isset(variable_get('booking_variety_regn_page')['value']) ? variable_get('booking_variety_regn_page')['value'] : $defaults,
'#type' => 'text_format',
'#format' => 'full_html',
);
//see http://drupal.org/node/820816#comment-3100356
//and http://drupal.org/node/823362
@@ -539,6 +390,10 @@ function booking_token_info() {
'name' => t('Event Contact Email'),
'description' => t('Contact email address for the current event.')
);
$info['tokens']['booking']['logistics-email'] = array(
'name' => t('Event Logistics Email'),
'description' => t('Logistics email address for the current event.')
);
$info['tokens']['booking']['eventdates'] = array(
'name' => t('Event Dates'),
'description' => t('Dates of the current event.')
@@ -575,6 +430,10 @@ function booking_token_info() {
'name' => t('Confirm Payment Link'),
'description' => t('If using paypal, the link to the booking confirmation page to complete a registration.')
);
$info['tokens']['booking']['booking-uuid'] = array(
'name' => t('Unique User ID'),
'description' => t('The unique user id used to create links to forms such as payment and travel.')
);
$info['tokens']['booking']['paypal-deposit-amount'] = array(
'name' => t('Paypal Deposit Only'),
'description' => t('The deposit amount required to confirm the registration including paypal fees.')
@@ -591,6 +450,26 @@ function booking_token_info() {
'name' => t('Paypal Total Form Button'),
'description' => t('The paypal form for the total amount.')
);
$info['tokens']['booking']['stripe-deposit-amount'] = array(
'name' => t('Stripe Deposit Only'),
'description' => t('The deposit amount required to confirm the registration including stripe fees. These tokens are only used for display purposes, not in the actual calculations.')
);
$info['tokens']['booking']['stripe-total-amount'] = array(
'name' => t('Stripe Outstanding Balance'),
'description' => t('The total amount required to complete the registration including stripe fees.')
);
$info['tokens']['booking']['stripe-total-amount-intl'] = array(
'name' => t('Stripe Outstanding Balance International'),
'description' => t('The total amount required to complete the registration including international or amex stripe fees.')
);
$info['tokens']['booking']['stripe-deposit-form'] = array(
'name' => t('Stripe Deposit Form Button'),
'description' => t('The stripe popup form for the deposit amount.')
);
$info['tokens']['booking']['stripe-total-form'] = array(
'name' => t('Stripe Total Form Button'),
'description' => t('The stripe popup form for the total amount.')
);
$info['tokens']['booking']['booking-id'] = array(
'name' => t('Booking ID'),
'description' => t('ID of the user\'s registration.')
@@ -617,7 +496,11 @@ function booking_token_info() {
);
$info['tokens']['booking']['leaderhelper-pair'] = array(
'name' => t('Registration Study Group Leader-Helper Pair'),
'description' => t('List out the leader and helper pairs, with intro text.')
'description' => t('List out the leader and helper pairs.')
);
$info['tokens']['booking']['readinggroup-listing'] = array(
'name' => t('Reading Group Membership'),
'description' => t('Lists all the people in a Reading Group, but only for the leader.')
);
$info['tokens']['booking']['room-allocation'] = array(
'name' => t('Room Allocation'),
@@ -631,6 +514,29 @@ function booking_token_info() {
'name' => t('Travel form Link'),
'description' => t('Link to the person\'s travel form.')
);
/*
$info['types']['meta-booking'] = array(
'name' => t('Meta Booking Tokens'),
'description' => t('Sub-tokens for the booking module that are used by other booking module tokens. They will only work in a very limited context.'),
'needs-data' => 'booking',
);
$info['tokens']['meta-booking']['studygroup-descrip'] = array(
'name' => t('Study Group Description'),
'description' => t('Used in the studygroup-summary token.')
);
$info['tokens']['meta-booking']['studygroup-weekday'] = array(
'name' => t('Study Group Weekday'),
'description' => t('Used in the studygroup-summary token.')
);
$info['tokens']['meta-booking']['studygroup-explan'] = array(
'name' => t('Study Group Explanation'),
'description' => t('Used in the studygroup-summary token.')
);
$info['tokens']['meta-booking']['studygroup-role'] = array(
'name' => t('Study Group Role'),
'description' => t('Used in the studygroup-summary token.')
);
*/
return $info;
}
@@ -663,7 +569,7 @@ function booking_tokens($type, $tokens, array $data = array(), array $options =
$replacements = array();
$sanitize = !empty($options['sanitize']);
if ($type == 'booking') {
if ($type == 'booking' || $type == 'meta-booking') {
foreach ($tokens as $name => $original) {
if (array_key_exists($name, $data)) {
$replacements[$original] = $data[$name];
@@ -696,6 +602,7 @@ function booking_define_tokens()
date("Y-m-d", $booking_times->booking_event_end));
$tokens['contact-us'] = l('contact us', 'contact-us');
$tokens['contact-email'] = variable_get('booking_contact_email');
$tokens['logistics-email'] = variable_get('booking_logistics_email');
$tokens['regn-count'] = $regncount_query->num_ppl;
$tokens['regn-limit'] = variable_get('booking_regn_limit',0);
return $tokens;
@@ -711,6 +618,7 @@ function booking_define_personspecific_tokens($node)
{
global $event;
$amount_paid = 0;
$payment_processor_type = variable_get('booking_payment_processor', 0);
//get a count of the total number of people booked in to this event
//but don't include people who haven't paid or have withdrawn their booking
@@ -740,34 +648,84 @@ function booking_define_personspecific_tokens($node)
$tokens = array();
$tokens['eventname'] = $event->booking_eventname;
$tokens['contact-email'] = variable_get('booking_contact_email');
$tokens['logistics-email'] = variable_get('booking_logistics_email');
$tokens['team-colour'] = ucwords($node->booking_readinggroup);
$tokens['fname'] = ucwords(trim($node->booking_firstname));
$tokens['lname'] = ucwords(trim($node->booking_lastname));
$tokens['dietary'] = ucwords(trim($node->booking_dietary));
$tokens['booking-id'] = $node->nid;
$tokens['booking-uuid'] = $tempid;
$tokens['payment-required'] = _booking_amount_owing($node, $amount_paid, FALSE);
$tokens['refund-due'] = $node->booking_refund_due;
$tokens['waitinglist-position'] = $result->num_ppl - variable_get('booking_regn_limit',350) + 1;
$tokens['payment-transaction-desc'] = $node->nid . ' ' . $node->booking_lastname;
$tokens['balance-payment-link'] = url('balance/' . $tempid, array('absolute' => TRUE));
$tokens['confirm-payment-link'] = url('confirm/' . $tempid, array('absolute' => TRUE));
$tokens['paypal-total-amount'] = _booking_amount_owing($node, $amount_paid);
$tokens['paypal-deposit-amount'] = _booking_deposit_amount($node, TRUE);
$tokens['regn-summary'] = _booking_details_email_summary($node);
if (variable_get('booking_enable_travelform', 0) == 1) {
$tokens['travel-link'] = url('travel/' . $tempid, array('absolute' => TRUE));
$tokens['travel-summary'] = _booking_travelform_email_summary($node);
// convert the URL into a href if html emails are enabled
if (variable_get('booking_enable_html_mail', 0) == 1) {
$balance_link = url('balance/' . $tempid, array('absolute' => TRUE));
$confirm_link = url('confirm/' . $tempid, array('absolute' => TRUE));
$tokens['balance-payment-link'] = "<a href=\"$balance_link\">$balance_link</a>";
$tokens['confirm-payment-link'] = "<a href=\"$confirm_link\">$confirm_link</a>";
}
else {
$tokens['balance-payment-link'] = url('balance/' . $tempid, array('absolute' => TRUE));
$tokens['confirm-payment-link'] = url('confirm/' . $tempid, array('absolute' => TRUE));
}
//if payment processor is set to manual then don't populate these tokens
//if paypal is enabled
if ($payment_processor_type == 0) {
$tokens['paypal-deposit-amount'] = _booking_deposit_amount($node, TRUE);
$tokens['paypal-total-amount'] = _booking_amount_owing($node, $amount_paid);
$tokens['stripe-deposit-amount'] = "";
$tokens['stripe-total-amount'] = "";
$tokens['stripe-total-amount-intl'] = "";
}
//if stripe is enabled
elseif ($payment_processor_type == 1) {
$tokens['paypal-deposit-amount'] = "";
$tokens['paypal-total-amount'] = "";
$tokens['stripe-deposit-amount'] = _booking_deposit_amount($node, TRUE);
$tokens['stripe-total-amount'] = _booking_amount_owing($node, $amount_paid, TRUE, FALSE);
$tokens['stripe-total-amount-intl'] = _booking_amount_owing($node, $amount_paid, TRUE, TRUE);
}
//if travelform is enabled
if (variable_get('booking_enable_travelform', 0) == 1) {
$tokens['travel-summary'] = _booking_travelform_email_summary($node);
// convert the URL into a href if html emails are enabled
if (variable_get('booking_enable_html_mail', 0) == 1) {
$travel_link = url('travel/' . $tempid, array('absolute' => TRUE));
$tokens['travel-link'] = "<a href=\"$travel_link\">$travel_link</a>";
}
else {
$tokens['travel-link'] = url('travel/' . $tempid, array('absolute' => TRUE));
}
}
// travel form not enabled
else {
$tokens['travel-link'] = "";
$tokens['travel-summary'] = "";
}
//if studygroups are enabled
if (variable_get('booking_enable_studygroups', 0) == 1) {
$tokens['studygroup-summary'] = _booking_studygroup_email_summary($node);
$tokens['leaderhelper-pair'] = _booking_leader_helper_email_summary($node);
$tokens['readinggroup-listing'] = _booking_readinggroup_email_listing($node);
}
if (variable_get('booking_enable_roomallocations', 0) == 1)
{
else {
$tokens['studygroup-summary'] = "";
$tokens['leaderhelper-pair'] = "";
}
//if room allocations are enabled
if (variable_get('booking_enable_roomallocations', 0) == 1) {
$tokens['room-allocation'] = _booking_room_email_summary($node);
$tokens['bed-type'] = _booking_room_bedtype_lookup(empty($node->booking_room_bedtype) ? '0' : $node->booking_room_bedtype);
}
else {
$tokens['room-allocation'] = "";
$tokens['bed-type'] = "";
}
//watchdog('booking_debug', "<pre>Person specific tokens:\n@info</pre>", array('@info' => print_r( $tokens, true)));
return $tokens;
}

View File

@@ -3,7 +3,8 @@
/**
* Travel form for attendee
*/
function booking_travel_page() {
function booking_travel_page()
{
global $event;
$output = "";
$return_array = array();
@@ -12,6 +13,14 @@ function booking_travel_page() {
if (!preg_match('/^[0-9A-Fa-f\-]+$/', arg(1))) {
//parameter from url is not what we were expecting
drupal_set_message("Error: Invalid session ID supplied. Please use the contact us form to let us know.", 'error', FALSE);
drupal_goto('content/travel');
return "";
}
//verify that this feature is enabled
if (variable_get('booking_enable_travelform', 0) == 0) {
drupal_set_message("Error: The travel form is not enabled. Please use the contact us form to inform the site owner of this error.", 'error', FALSE);
drupal_goto('content/travel');
return "";
}
@@ -19,40 +28,58 @@ function booking_travel_page() {
$query = db_select('booking_person', 'p');
$query->condition('p.booking_tempid', arg(1), '=')
->fields('p', array('nid'));
$person = $query->execute()
->fetchObject();
$person = $query->execute()->fetchObject();
//if we found a matching person
if ($person)
{
if ($person) {
//load this person's data
$node = node_load($person->nid);
$tokens = booking_define_personspecific_tokens($node);
//watchdog('booking', 'Checking for existing travel form for: @info', array('@info' => var_export($person, TRUE)));
//check for an existing travel form
if (! empty( $node->tid ))
{
$output = token_replace(variable_get('booking_travelform_completed_page'), $tokens);
$return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output));
if (!empty($node->tid)) {
$inputtext = variable_get('booking_travelform_completed_page');
//$output = token_replace(variable_get('booking_travelform_completed_page'), $tokens);
$return_array[] = array(
'paragraph' => array(
'#type' => 'markup',
'#markup' => token_replace($inputtext['value'], $tokens),
)
);
}
//they haven't submitted a travel form yet
else
{
else {
//Output different text if this is for a married couple
if ((variable_get('booking_enable_combined_pricing', 0) == 1) && $node->booking_partner_id > 0)
{
$output = token_replace(variable_get('booking_travelform_married_page'), $tokens);
if ((variable_get('booking_enable_combined_pricing', 0) == 1) && $node->booking_partner_id > 0) {
$inputtext = variable_get('booking_travelform_married_page');
//$output = token_replace(variable_get('booking_travelform_married_page'), $tokens);
} else {
$inputtext = variable_get('booking_travelform_page');
//$output = token_replace(variable_get('booking_travelform_page'), $tokens);
}
else
{
$output = token_replace(variable_get('booking_travelform_page'), $tokens);
}
$return_array[] = array('paragraph' => array('#type' => 'markup', '#markup' => $output));
$return_array[] = array('form' => drupal_get_form('travel_form', true, $node->nid));
//text before form
$return_array[] = array(
'paragraph' => array(
'#type' => 'markup',
'#markup' => token_replace($inputtext['value'], $tokens),
)
);
//actual form
$return_array[] = array(
'form' => drupal_get_form('travel_form', $node, true, $tokens)
);
//text after form
/*
$afterform_text = variable_get('booking_travelform_page_post_text');
$return_array[] = array(
'paragraph' => array(
'#type' => 'markup',
'#markup' => token_replace($afterform_text['value'], $tokens),
)
);
*/
}
return $return_array;
@@ -64,7 +91,8 @@ function booking_travel_page() {
}
function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
//function travel_form($node, &$form_state, $inserting = FALSE, $node = NULL, $tokens = NULL)
function travel_form($node, &$form_state, $db_node = NULL, $inserting = FALSE, $tokens = NULL)
{
global $event;
date_default_timezone_set(date_default_timezone(FALSE));
@@ -72,46 +100,63 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
$booking_dietary = '';
$booking_medical_conditions = '';
$booking_bf_gf_nid = '';
$booking_partner_id = '';
$booking_roommate = '';
$transport_type_options = array(
'Driving' => 'Driving',
//'Train' => 'Train',
'Flying' => 'Flying'
'Flying' => 'Flying',
);
//there's already info in $node so use that
if (!empty($node))
{
$data = $node;
if (!empty($db_node)) {
$data = $db_node;
//watchdog('booking_debug', "<pre>Travel form loaded from travel page:\n@info</pre>", array('@info' => print_r( $data, true)));
}
//otherwise rely on the form state from the previous submission
else
{
$data = $form_state['input'];
else {
$data = $form_state['node'];
//watchdog('booking_debug', "<pre>Travel form loaded directly:\n@info</pre>", array('@info' => print_r( $data, true)));
}
//get info about this person from the relevant node id
$person = db_query("SELECT booking_dietary, booking_medical_conditions, booking_bf_gf_nid, booking_partner_id, booking_room_mate1 " .
"FROM {booking_person} " .
"WHERE nid = :nid ",
array(':nid' => $nid <> 0 ? $nid : $data->booking_person_nid))
->fetchObject();
//get info from the database if we don't have it
if (! isset($data->booking_partner_id)) {
watchdog('booking_debug', "<pre>Travel form querying database for missing details</pre>");
if ($person)
{
$person = db_query("SELECT booking_dietary, booking_medical_conditions, booking_bf_gf_nid, booking_partner_id, booking_room_mate1 " .
"FROM {booking_person} " . "WHERE nid = :nid ",
array(':nid' => isset($data->booking_person_nid) ? $data->booking_person_nid : $data->nid))->fetchObject();
//check we got results
if ($person) {
watchdog('booking_debug', "<pre>Person info from database:\n@info</pre>", array('@info' => print_r( $person, true)));
$booking_dietary = $person->booking_dietary;
$booking_medical_conditions = $person->booking_medical_conditions;
//an empty value is zero in this case
$booking_bf_gf_nid = $person->booking_bf_gf_nid == 0 ? '' : $person->booking_bf_gf_nid;
$booking_partner_id = $person->booking_partner_id == 0 ? '' : $person->booking_partner_id;
$booking_roommate = $person->booking_room_mate1;
}
else {
watchdog('booking_debug', "<pre>Failed to retrieve person from database using nid from data variable:\n@info</pre>", array('@info' => print_r( $data, true)));
}
}
else {
//watchdog('booking_debug', "<pre>Travel form not querying database for missing details</pre>");
$booking_dietary = $data->booking_dietary;
$booking_medical_conditions = $data->booking_medical_conditions;
//an empty value is zero in this case
$booking_bf_gf_nid = $data->booking_bf_gf_nid == 0 ? '' : $data->booking_bf_gf_nid;
$booking_partner_id = $data->booking_partner_id == 0 ? '' : $data->booking_partner_id;
$booking_roommate = $data->booking_room_mate1;
}
//form starts here
//store the node id
$form['personid'] = array(
'#type' => 'hidden',
'#value' => $nid,
'#value' => $data->nid,
);
$form['travel'] = array(
@@ -123,7 +168,7 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
'#title' => t('Transport Type'),
'#options' => $transport_type_options,
'#default_value' => !empty($data->booking_transport_type) ? $data->booking_transport_type : NULL,
'#required' => TRUE,
'#required' => TRUE
);
/*
@@ -147,9 +192,11 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
'#default_value' => empty($data->booking_flightnum_inbound) ? '' : $data->booking_flightnum_inbound,
'#states' => array(
'visible' => array(
':input[name="booking_transport_type"]' => array('value' => 'Flying'),
),
),
':input[name="booking_transport_type"]' => array(
'value' => 'Flying'
)
)
)
);
$form['travel']['booking_flight_datetime_inbound'] = array(
'#type' => 'date_select',
@@ -160,9 +207,11 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
'#date_year_range' => '0:0',
'#states' => array(
'visible' => array(
':input[name="booking_transport_type"]' => array('value' => 'Flying'),
),
),
':input[name="booking_transport_type"]' => array(
'value' => 'Flying'
)
)
)
);
$form['travel']['booking_flightnum_outbound'] = array(
'#type' => 'textfield',
@@ -171,9 +220,11 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
'#default_value' => empty($data->booking_flightnum_outbound) ? '' : $data->booking_flightnum_outbound,
'#states' => array(
'visible' => array(
':input[name="booking_transport_type"]' => array('value' => 'Flying'),
),
),
':input[name="booking_transport_type"]' => array(
'value' => 'Flying'
)
)
)
);
$form['travel']['booking_flight_datetime_outbound'] = array(
'#type' => 'date_select',
@@ -184,32 +235,42 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
'#date_year_range' => '0:0',
'#states' => array(
'visible' => array(
':input[name="booking_transport_type"]' => array('value' => 'Flying'),
),
),
':input[name="booking_transport_type"]' => array(
'value' => 'Flying'
)
)
)
);
$form['travel']['booking_transport_from_morriset_reqd'] = array(
'#type' => 'radios',
'#title' => t('Will you be catching the train to Study Week?'),
'#options' => array('Yes' => 'Yes I will be catching the train', 'No' => 'No - I have arranged my own Transport'),
'#options' => array(
'Yes' => 'Yes I will be catching the train',
'No' => 'No - I have arranged my own Transport'
),
'#default_value' => (!isset($data->booking_transport_from_morriset_reqd)) ? 'No' : ($data->booking_transport_from_morriset_reqd == 1 ? 'Yes' : 'No'),
'#states' => array(
'visible' => array(
':input[name="booking_transport_type"]' => array('value' => 'Flying'),
),
),
':input[name="booking_transport_type"]' => array(
'value' => 'Flying'
)
)
)
);
$form['accommodation'] = array(
'#type' => 'fieldset',
'#title' => 'Accommodation Details',
'#title' => 'Accommodation Details'
);
$form['accommodation']['booking_accom_before_reqd'] = array(
'#type' => 'radios',
'#title' => t('Do you need us to organise accommodation before Study Week?'),
'#options' => array('Yes' => 'Yes', 'No' => "No - I have arranged my own accommodation or I'm not arriving early"),
'#default_value' => (! isset($data->booking_accom_before_reqd)) ? 'No' : ($data->booking_accom_before_reqd == 1 ? 'Yes' : 'No'),
'#options' => array(
'Yes' => 'Yes',
'No' => "No - I have arranged my own accommodation or I'm not arriving early"
),
'#default_value' => (!isset($data->booking_accom_before_reqd)) ? 'No' : ($data->booking_accom_before_reqd == 1 ? 'Yes' : 'No')
);
/*
$form['accommodation']['booking_accom_before_staying_with'] = array(
@@ -227,8 +288,11 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
$form['accommodation']['booking_accom_after_reqd'] = array(
'#type' => 'radios',
'#title' => t('Do you need us to organise accommodation after Study Week?'),
'#options' => array('Yes' => 'Yes', 'No' => "No - I have arranged my own accommodation or I'm not staying in Sydney afterwards"),
'#default_value' => (! isset($data->booking_accom_after_reqd)) ? 'No' : ($data->booking_accom_after_reqd == 1 ? 'Yes' : 'No'),
'#options' => array(
'Yes' => 'Yes',
'No' => "No - I have arranged my own accommodation or I'm not staying in Sydney afterwards"
),
'#default_value' => (!isset($data->booking_accom_after_reqd)) ? 'No' : ($data->booking_accom_after_reqd == 1 ? 'Yes' : 'No')
);
/*
$form['accommodation']['booking_accom_after_staying_with'] = array(
@@ -243,175 +307,169 @@ function travel_form($node, &$form_state, $inserting = FALSE, $nid = 0)
),
);
*/
//calculate which fields to show and whether we need to show the fieldset at all
$show_dietary = ((variable_get('booking_enable_dietary', 0) == 1) || ($inserting == FALSE));
$show_medical = ((variable_get('booking_enable_medcond', 0) == 1) || ($inserting == FALSE));
$show_roommate = (variable_get('booking_enable_roommate', 0) == 1 && $booking_partner_id == 0) || $inserting == FALSE;
$show_bf_gf = $booking_partner_id == 0 || $inserting == FALSE;
$show_special_requirements = ($show_dietary || $show_medical || $show_roommate || $show_bf_gf);
if ($show_special_requirements) {
$form['requirements'] = array(
'#type' => 'fieldset',
'#title' => 'Special Requirements',
'#title' => 'Special Requirements'
);
}
//only show the dietary field if we're allowed to
if (variable_get('booking_enable_dietary', 0) == 1 || $inserting == FALSE)
{
if ($show_dietary) {
$form['requirements']['booking_dietary'] = array(
'#type' => 'textfield',
'#title' => t('Special dietary requirements?'),
'#maxlength' => 180,
'#default_value' => !empty($data->booking_dietary) ? $data->booking_dietary : $booking_dietary,
'#default_value' => !empty($data->booking_dietary) ? $data->booking_dietary : $booking_dietary
);
}
//display the medical conditions question if it is enabled
if ($show_medical) {
$form['requirements']['booking_medical_conditions'] = array(
'#type' => 'textfield',
'#title' => t('Please describe any medical condition we need to know about.'),
'#description' => t('This field contains information you entered when you registered.'),
'#maxlength' => 180,
'#required' => FALSE,
'#default_value' => !empty($data->booking_medical_conditions) ? $data->booking_medical_conditions : $booking_medical_conditions,
'#default_value' => !empty($data->booking_medical_conditions) ? $data->booking_medical_conditions : $booking_medical_conditions
);
//only show the room mate field if we're allowed to
if (variable_get('booking_enable_roommate', 0) == 1 || $inserting == FALSE)
{
//married people won't need to select a room mate
if ((variable_get('booking_enable_combined_pricing', 0) == 1) && $person->booking_partner_id == 0)
{
}
//only show the room mate field if we're allowed to and the person isn't married
if ($show_roommate) {
$form['requirements']['booking_room_mate1'] = array(
'#type' => 'textfield',
'#title' => t('I would like to share a room with'),
'#description' => t('This field contains information you entered when you registered. Update if necessary.'),
'#maxlength' => 200,
'#required' => FALSE,
'#default_value' => !empty($data->booking_room_mate1) ? $data->booking_room_mate1 : $booking_roommate,
'#default_value' => !empty($data->booking_room_mate1) ? $data->booking_room_mate1 : $booking_roommate
);
}
}
//only show this field if this person isn't married
if ((variable_get('booking_enable_combined_pricing', 0) == 1) && $person->booking_partner_id == 0)
{
if ($show_bf_gf) {
$form['requirements']['booking_bf_gf_nid'] = array(
'#type' => 'textfield',
'#title' => t('Registration ID of Boyfriend/Girlfriend to be placed in the same discussion groups as you.'),
'#description' => t('If you\'re not sure what this number is, ask your Significant Other to look at the confirmation email they received when they registered.'),
'#maxlength' => 15,
'#size' => 4,
'#required' => FALSE,
'#default_value' => !empty($data->booking_bf_gf_nid) ? $data->booking_bf_gf_nid : $booking_bf_gf_nid,
'#default_value' => !empty($data->booking_bf_gf_nid) ? $data->booking_bf_gf_nid : $booking_bf_gf_nid
);
}
if ($inserting == TRUE) {
//add some html just before the submit button
$afterform_text = variable_get('booking_travelform_page_post_text');
$form['post-text'] = array(
'#type' => 'container',
'#children' => token_replace($afterform_text['value'], $tokens),
);
//include the submit button
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#value' => t('Submit')
);
}
return $form;
}
function travel_form_validate($form, &$form_state) {
//watchdog('booking', "<pre>Travel form:\n@info</pre>", array('@info' => print_r( $form_state, true)));
//watchdog('booking_debug', "<pre>Travel form:\n@info</pre>", array('@info' => print_r( $form_state, true)));
//verify boyfriend/girlfriend id is in the correct format
if (isset($form_state['values']['booking_bf_gf_nid']) && $form_state['values']['booking_bf_gf_nid'] != '')
{
if (isset($form_state['values']['booking_bf_gf_nid']) && $form_state['values']['booking_bf_gf_nid'] != '') {
//make sure this is a node id not something else
if (! is_numeric($form_state['values']['booking_bf_gf_nid'] ))
{
form_set_error('booking_bf_gf_nid',
t('You have entered an invalid registration id for your boyfriend/girlfriend. ' .
if (!is_numeric($form_state['values']['booking_bf_gf_nid'])) {
form_set_error('booking_bf_gf_nid', t('You have entered an invalid registration id for your boyfriend/girlfriend. ' .
'Please ensure you are using only the registration reference number your boyfriend/girlfriend received via email. For example, your registration ID is !id. ' .
'If you believe this to be incorrect, please !contact using the details provided.',
array('!id' => $form_state['values']['personid'], '!contact' => l('contact us', 'contact')))
);
watchdog('booking', "<pre>Travel form non-numeric bf/gf\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
array(
'!id' => $form_state['values']['personid'],
'!contact' => l('contact us', 'contact')
)));
watchdog('booking', "<pre>Travel form non-numeric bf/gf\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
//don't allow them to specify their own node id
elseif ($form_state['values']['personid'] == $form_state['values']['booking_bf_gf_nid'])
{
form_set_error('booking_bf_gf_nid',
t('You have entered your own registration id.' .
'Please ensure you enter only the registration reference number your boyfriend/girlfriend received via email when registering, not your own registration id.')
);
watchdog('booking', "<pre>Travel form bf/gf same as person id\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
}
else
{
elseif ($form_state['values']['personid'] == $form_state['values']['booking_bf_gf_nid']) {
form_set_error('booking_bf_gf_nid', t('You have entered your own registration id. ' .
'Please ensure you enter only the registration reference number your boyfriend/girlfriend received via email when registering, not your own registration id.'));
watchdog('booking', "<pre>Travel form bf/gf same as person id\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
} else {
//check that the partner exists
$partner = db_query("SELECT person.nid " .
"FROM {booking_person} person " .
"WHERE nid = :nid",
array(':nid' => $form_state['values']['booking_bf_gf_nid']))
->fetchObject();
if (! $partner)
{
form_set_error('booking_bf_gf_nid',
t('We cannot find a matching registration id for your boyfriend/girlfriend. ' .
$partner = db_query("SELECT person.nid " . "FROM {booking_person} person " . "WHERE nid = :nid", array(
':nid' => $form_state['values']['booking_bf_gf_nid']
))->fetchObject();
if (!$partner) {
form_set_error('booking_bf_gf_nid', t('We cannot find a matching registration id for your boyfriend/girlfriend. ' .
'Please ensure you are using only the number that relates to their registration. For example, your registration ID is !id. ' .
'If you believe this to be incorrect, please !contact using the details provided.',
array('!id' => $form_state['values']['personid'], '!contact' => l('contact us', 'contact')))
);
watchdog('booking', "<pre>Travel form unknown bf/gf id\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
array(
'!id' => $form_state['values']['personid'],
'!contact' => l('contact us', 'contact')
)));
watchdog('booking', "<pre>Travel form unknown bf/gf id\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
} //end missing partner handling
} //end bf/gf validation
} //end bf/gf checking
//check to make sure flight info is entered if it is selected
if (isset($form_state['values']['booking_transport_type']) && $form_state['values']['booking_transport_type'] == 'Flying')
{
if (isset($form_state['values']['booking_transport_type']) && $form_state['values']['booking_transport_type'] == 'Flying') {
if ( (! isset($form_state['values']['booking_flightnum_inbound'])) || ($form_state['values']['booking_flightnum_inbound'] == '') )
{
form_set_error('booking_flightnum_inbound',
t('Please enter the flight number associated with your arrival flight.')
);
watchdog('booking', "<pre>Travel form missing flight number for arrival flight\n@info</pre>",
array('@info' => print_r( $form_state['values'], true)));
if ((!isset($form_state['values']['booking_flightnum_inbound'])) || ($form_state['values']['booking_flightnum_inbound'] == '')) {
form_set_error('booking_flightnum_inbound', t('Please enter the flight number associated with your arrival flight.'));
watchdog('booking', "<pre>Travel form missing flight number for arrival flight\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
if (
$form_state['values']['booking_flight_datetime_inbound']['day'] == '' ||
$form_state['values']['booking_flight_datetime_inbound']['month'] == '' ||
$form_state['values']['booking_flight_datetime_inbound']['year'] == '' ||
$form_state['values']['booking_flight_datetime_inbound']['hour'] == '' ||
$form_state['values']['booking_flight_datetime_inbound']['minute'] == ''
)
{
form_set_error('booking_flight_datetime_inbound',
t('Please enter the arrival time associated with your flight.')
);
watchdog('booking', "<pre>Travel form missing flight arrival time\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
if (!isset($form_state['values']['booking_flight_datetime_inbound'])) {
form_set_error('booking_flight_datetime_inbound', t('Please enter the arrival time associated with your flight.'));
watchdog('booking_debug', "<pre>Travel form missing flight arrival time\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
if ( (! isset($form_state['values']['booking_flightnum_outbound'])) || ($form_state['values']['booking_flightnum_outbound'] == '') )
{
form_set_error('booking_flightnum_outbound',
t('Please enter the flight number associated with your departing flight.')
);
watchdog('booking', "<pre>Travel form missing flight number for departing flight\n@info</pre>",
array('@info' => print_r( $form_state['values'], true)));
if ((!isset($form_state['values']['booking_flightnum_outbound'])) || ($form_state['values']['booking_flightnum_outbound'] == '')) {
form_set_error('booking_flightnum_outbound', t('Please enter the flight number associated with your departing flight.'));
watchdog('booking', "<pre>Travel form missing flight number for departing flight\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
if (
$form_state['values']['booking_flight_datetime_outbound']['day'] == '' ||
$form_state['values']['booking_flight_datetime_outbound']['month'] == '' ||
$form_state['values']['booking_flight_datetime_outbound']['year'] == '' ||
$form_state['values']['booking_flight_datetime_outbound']['hour'] == '' ||
$form_state['values']['booking_flight_datetime_outbound']['minute'] == ''
)
{
form_set_error('booking_flight_datetime_outbound',
t('Please enter the departure time associated with your flight.')
);
watchdog('booking', "<pre>Travel form missing flight departure time\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
if (!isset($form_state['values']['booking_flight_datetime_outbound'])) {
form_set_error('booking_flight_datetime_outbound', t('Please enter the departure time associated with your flight.'));
watchdog('booking', "<pre>Travel form missing flight departure time\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
//check for arrival time after departure time
if (_datetime_to_ts($form_state['values']['booking_flight_datetime_inbound']) > _datetime_to_ts($form_state['values']['booking_flight_datetime_outbound']))
{
form_set_error('booking_flight_datetime_inbound',
t('You have entered an arrival flight time that is after your departure flight time.')
);
watchdog('booking', "<pre>Travel form seems to have arrival flight after departure flight\n@info</pre>", array('@info' => print_r( $form_state['values'], true)));
if (_datetime_to_ts($form_state['values']['booking_flight_datetime_inbound']) > _datetime_to_ts($form_state['values']['booking_flight_datetime_outbound'])) {
form_set_error('booking_flight_datetime_inbound', t('You have entered an arrival flight time that is after your departure flight time.'));
watchdog('booking', "<pre>Travel form seems to have arrival flight after departure flight\n@info</pre>", array(
'@info' => print_r($form_state['values'], true)
));
}
} //end check for flying
} //end validation
}
function travel_form_submit($form, &$form_state) {
function travel_form_submit($form, &$form_state)
{
global $event;
$values = $form_state['input'];
@@ -425,17 +483,17 @@ function travel_form_submit($form, &$form_state) {
}
//fetch details about the person
$person = db_query("SELECT nid as personid, booking_tempid, booking_firstname, booking_lastname, booking_partner_id, booking_dietary, booking_room_mate1 " .
"FROM {booking_person} " .
"WHERE nid = :nid ",
array(':nid' => $values['personid']))
->fetchObject();
$person = db_query("SELECT nid as personid, booking_tempid, booking_firstname, booking_lastname, booking_partner_id, booking_dietary, booking_room_mate1, booking_medical_conditions " . "FROM {booking_person} " . "WHERE nid = :nid ", array(
':nid' => $values['personid']
))->fetchObject();
//create the new node structure
$node = new stdClass();
$node = node_type_set_defaults();
$node->title = t('!event travel form: !name',
array('!event' => $event->booking_eventname, '!name' => $person->booking_firstname . ' ' . $person->booking_lastname));
$node->title = t('!event travel form: !name', array(
'!event' => $event->booking_eventname,
'!name' => $person->booking_firstname . ' ' . $person->booking_lastname
));
$node->type = 'travel';
$node->status = 1; // Published?
$node->promote = 0; // Display on front page?
@@ -458,10 +516,10 @@ function travel_form_submit($form, &$form_state) {
//$node->booking_accom_after_staying_with = $values['booking_accom_after_staying_with'];
//booking_person related fields
$node->booking_medical_conditions = $values['booking_medical_conditions'];
$node->booking_bf_gf_nid = empty($values['booking_bf_gf_nid']) ? 0 : $values['booking_bf_gf_nid'];
//optional fields
$node->booking_medical_conditions = variable_get('booking_enable_medcond', 0) == 1 ? $values['booking_medical_conditions'] : $person->booking_medical_conditions;
$node->booking_dietary = variable_get('booking_enable_dietary', 0) == 1 ? $values['booking_dietary'] : $person->booking_dietary;
//room mate field might be enabled but not displayed for a married couple so calculate whether the field is empty or not first
$room_mate = empty($values['booking_room_mate1']) ? $person->booking_room_mate1 : $values['booking_room_mate1'];
@@ -478,10 +536,10 @@ function travel_form_submit($form, &$form_state) {
drupal_set_message("Thanks for submitting your travel details. You should receive a confirmation email shortly.", $type = 'status');
$form_state['redirect'] = array('content/travel');
}
function travel_load($nodes) {
function travel_load($nodes)
{
//watchdog('booking', 'Loading node with params: @info', array('@info' => var_export($nodes, TRUE)));
// note that $nodes is an array of object references, keyed by nid
@@ -491,17 +549,20 @@ function travel_load($nodes) {
$query->distinct();
$query->join('booking_person', 'p', 'p.nid = t.booking_person_nid');
$query->fields('t');
$query->fields('p', array('booking_dietary','booking_medical_conditions','booking_bf_gf_nid', 'booking_room_mate1'));
$query->fields('p', array(
'booking_dietary',
'booking_medical_conditions',
'booking_bf_gf_nid',
'booking_room_mate1'
));
$query->condition('tid', array_keys($nodes), 'IN');
$result = $query->execute();
//add that data to the array of node references
foreach ($result as $record)
{
foreach ($result as $record) {
//watchdog('booking', 'This node looks like: @info', array('@info' => var_export($record, TRUE)));
// run through each result row and add in the needed attributes
foreach ($record as $key => $value)
{
foreach ($record as $key => $value) {
$nodes[$record->tid]->$key = $value;
}
}
@@ -512,10 +573,9 @@ function travel_load($nodes) {
function travel_insert($node)
{
//watchdog('booking', 'Inserting travel form: @info', array('@info' => var_export($node, TRUE)));
watchdog('booking_debug', "<pre>Inserting travel form:\n@info</pre>", array('@info' => print_r($node, TRUE)));
db_insert('booking_travel')
->fields(array(
db_insert('booking_travel')->fields(array(
'tid' => $node->nid,
'booking_person_nid' => $node->booking_person_nid,
'booking_transport_type' => $node->booking_transport_type,
@@ -527,39 +587,32 @@ function travel_insert($node)
'booking_flight_datetime_outbound' => $node->booking_flight_datetime_outbound,
'booking_accom_before_reqd' => $node->booking_accom_before_reqd,
//'booking_accom_before_staying_with' => $node->booking_accom_before_staying_with,
'booking_accom_after_reqd' => $node->booking_accom_after_reqd,
'booking_accom_after_reqd' => $node->booking_accom_after_reqd
//'booking_accom_after_staying_with' => $node->booking_accom_after_staying_with,
))
->execute();
))->execute();
//update the booking_person fields
db_update('booking_person')
->fields(array(
db_update('booking_person')->fields(array(
'booking_dietary' => $node->booking_dietary,
'booking_medical_conditions' => $node->booking_medical_conditions,
'booking_bf_gf_nid' => $node->booking_bf_gf_nid,
'booking_room_mate1' => $node->booking_room_mate1,
))
->condition('nid', $node->booking_person_nid)
->execute();
'booking_room_mate1' => $node->booking_room_mate1
))->condition('nid', $node->booking_person_nid)->execute();
//set the boyfriend/girlfriend to point to this person
if ($node->booking_bf_gf_nid <> 0)
{
db_update('booking_person')
->fields(array(
'booking_bf_gf_nid' => $node->booking_person_nid,
))
->condition('nid', $node->booking_bf_gf_nid)
->execute();
if ($node->booking_bf_gf_nid <> 0) {
db_update('booking_person')->fields(array(
'booking_bf_gf_nid' => $node->booking_person_nid
))->condition('nid', $node->booking_bf_gf_nid)->execute();
}
}
function travel_update($node)
{
watchdog('booking', 'Updating travel form booking_travel table: @info', array('@info' => var_export($node, TRUE)));
db_update('booking_travel')
->fields(array(
watchdog('booking', 'Updating travel form booking_travel table: @info', array(
'@info' => var_export($node, TRUE)
));
db_update('booking_travel')->fields(array(
'tid' => $node->nid,
'booking_person_nid' => $node->booking_person_nid,
'booking_transport_type' => $node->booking_transport_type,
@@ -571,91 +624,128 @@ function travel_update($node)
'booking_flight_datetime_outbound' => _datetime_to_ts($node->booking_flight_datetime_outbound),
'booking_accom_before_reqd' => $node->booking_accom_before_reqd == 'Yes' ? 1 : 0,
//'booking_accom_before_staying_with' => $node->booking_accom_before_staying_with,
'booking_accom_after_reqd' => $node->booking_accom_after_reqd == 'Yes' ? 1 : 0,
'booking_accom_after_reqd' => $node->booking_accom_after_reqd == 'Yes' ? 1 : 0
//'booking_accom_after_staying_with' => $node->booking_accom_after_staying_with,
))
->condition('tid', $node->nid)
->execute();
))->condition('tid', $node->nid)->execute();
watchdog('booking', 'Updating travel form booking_person table');
//update the booking_person fields
db_update('booking_person')
->fields(array(
db_update('booking_person')->fields(array(
'booking_dietary' => $node->booking_dietary,
'booking_medical_conditions' => $node->booking_medical_conditions,
'booking_bf_gf_nid' => $node->booking_bf_gf_nid == '' ? 0 : $node->booking_bf_gf_nid,
'booking_room_mate1' => $node->booking_room_mate1,
))
->condition('nid', $node->booking_person_nid)
->execute();
'booking_room_mate1' => $node->booking_room_mate1
))->condition('nid', $node->booking_person_nid)->execute();
//set the boyfriend/girlfriend to point to this person
if ($node->booking_bf_gf_nid <> 0)
{
db_update('booking_person')
->fields(array(
'booking_bf_gf_nid' => $node->booking_person_nid,
))
->condition('nid', $node->booking_bf_gf_nid)
->execute();
if ($node->booking_bf_gf_nid <> 0) {
db_update('booking_person')->fields(array(
'booking_bf_gf_nid' => $node->booking_person_nid
))->condition('nid', $node->booking_bf_gf_nid)->execute();
}
}
function travel_delete($node)
{
$person_id = $node->booking_person_nid;
$num_deleted = db_delete('booking_travel')
->condition('tid', $node->nid)
->execute();
$message = t("Successfully deleted !num row(s) from the booking_travel table, corresponding to person ID !id",
array('!num' => $num_deleted, '!id' => $person_id));
$num_deleted = db_delete('booking_travel')->condition('tid', $node->nid)->execute();
$message = t("Successfully deleted !num row(s) from the booking_travel table, corresponding to person ID !id", array(
'!num' => $num_deleted,
'!id' => $person_id
));
drupal_set_message($message, $type = 'status');
}
function travel_view($node, $view_mode) {
global $event;
//fetch details about the person
$person = db_query("SELECT p.*, t.* from {booking_person} p " .
"left outer join {booking_travel} t on p.nid = t.booking_person_nid " .
"where p.nid = :nid",
array(':nid' => $node->booking_person_nid))
->fetchObject();
//and their boyfriend/girlfriend if it is defined
if ($person->booking_bf_gf_nid != 0)
function travel_view($node, $view_mode)
{
$query = db_query("Select booking_firstname, booking_lastname from {booking_person} where nid = :nid",
array(':nid' => $node->booking_bf_gf_nid))
->fetchObject();
$bf_gf = $query->booking_firstname . " " . $query->booking_lastname;
}
else
$bf_gf = "N/A";
global $event;
$header = array('Attribute', 'Value');
$rows = array();
$rows[] = array(t('Name:'), l(t('!first !last', array('!first' => $person->booking_firstname, '!last' => $person->booking_lastname)),
t('node/!id', array('!id' => $node->booking_person_nid))),);
$rows[] = array(t('Transport Type:'), $node->booking_transport_type);
$rows[] = array(t('Catching the train to Study Week:'), $node->booking_transport_from_morriset_reqd == 1 ? 'Yes' : 'No');
$rows[] = array(t('Inbound Flight Number:'), $node->booking_flightnum_inbound);
$rows[] = array(t('Flight Arrival:'), t('!date', array('!date' => format_date($node->booking_flight_datetime_inbound, 'custom', 'd/m/Y H:i'))));
$rows[] = array(t('Outbound Flight Number:'), $node->booking_flightnum_outbound);
$rows[] = array(t('Flight Departure:'), t('!date', array('!date' => format_date($node->booking_flight_datetime_outbound, 'custom', 'd/m/Y H:i'))));
$rows[] = array(t('Accommodation before Study Week Required:'), $node->booking_accom_before_reqd == 1 ? 'Yes' : 'No');
$rows[] = array(t('Accommodation after Study Week Required:'), $node->booking_accom_after_reqd == 1 ? 'Yes' : 'No');
//fetch details about the person
$person = db_query("SELECT p.*, t.* from {booking_person} p " . "left outer join {booking_travel} t on p.nid = t.booking_person_nid " . "where p.nid = :nid", array(
':nid' => $node->booking_person_nid
))->fetchObject();
//and their boyfriend/girlfriend if it is defined
if ($person->booking_bf_gf_nid != 0) {
$query = db_query("Select booking_firstname, booking_lastname from {booking_person} where nid = :nid", array(
':nid' => $node->booking_bf_gf_nid))->fetchObject();
$bf_gf = l(t('!first !last', array('!first' => $query->booking_firstname, '!last' => $query->booking_lastname)),
t('node/!id', array('!id' => $person->booking_bf_gf_nid,
)));
}
else {
$bf_gf = "N/A";
}
$rows[] = array(
t('Name:'),
l(t('!first !last', array(
'!first' => $person->booking_firstname,
'!last' => $person->booking_lastname,
)), t('node/!id', array(
'!id' => $node->booking_person_nid
)))
);
$rows[] = array(
t('Transport Type:'),
$node->booking_transport_type
);
$rows[] = array(
t('Catching the train to Study Week:'),
$node->booking_transport_from_morriset_reqd == 1 ? 'Yes' : 'No'
);
$rows[] = array(
t('Inbound Flight Number:'),
$node->booking_flightnum_inbound
);
$rows[] = array(
t('Flight Arrival:'),
t('!date', array('!date' => $node->booking_flight_datetime_inbound == 0 ? '' : format_date($node->booking_flight_datetime_inbound, 'custom', 'd/m/Y H:i')
))
);
$rows[] = array(
t('Outbound Flight Number:'),
$node->booking_flightnum_outbound
);
$rows[] = array(
t('Flight Departure:'),
t('!date', array('!date' => $node->booking_flight_datetime_outbound == 0 ? '' : format_date($node->booking_flight_datetime_outbound, 'custom', 'd/m/Y H:i')
))
);
$rows[] = array(
t('Accommodation before Study Week Required:'),
$node->booking_accom_before_reqd == 1 ? 'Yes' : 'No'
);
$rows[] = array(
t('Accommodation after Study Week Required:'),
$node->booking_accom_after_reqd == 1 ? 'Yes' : 'No'
);
//fields from booking_person
$rows[] = array(t('Special Dietary Requirements:'), $node->booking_dietary);
$rows[] = array(t('Special Medical Conditions:'), $node->booking_medical_conditions);
$rows[] = array(t('Boyfriend/Girlfriend:'), $bf_gf);
$rows[] = array(t('Requested Room mate(s):'), $node->booking_room_mate1);
$rows[] = array(
t('Special Dietary Requirements:'),
$node->booking_dietary
);
$rows[] = array(
t('Special Medical Conditions:'),
$node->booking_medical_conditions
);
$rows[] = array(
t('Boyfriend/Girlfriend:'),
$bf_gf
);
$rows[] = array(
t('Requested Room mate(s):'),
$node->booking_room_mate1
);
$node->content['details'] = array(
'#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
'#weight' => 1,
'#markup' => theme('table', array(
'header' => $header,
'rows' => $rows
)),
'#weight' => 1
);
return $node;
}

View File

@@ -1,432 +0,0 @@
<?php
/**
* @file
* Admin pages for configuring a variety session
*/
function booking_variety_admin()
{
//see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios
// tableselect with text fields http://drupal.stackexchange.com/questions/75950/tableselect-with-textfields/82763#82763
// inline edit buttons http://drupal.stackexchange.com/questions/31942/how-do-i-add-an-edit-button-on-each-row-of-a-tableselect-form-element
// tabledrag example http://dropbucket.org/node/204
$form = array ();
$options = array ();
//$prefix = t("<p>!link</p>",
// array ('!link' => l('Add New Variety Timeslot', 'admin/config/booking/variety/create')));
$header = array (
'tid' => t('Event ID'),
'booking_variety_time_descrip' => t('Description'),
'booking_variety_status' => t('Status'),
'booking_variety_start' => t('Timeslot Start'),
'booking_variety_end' => t('Timeslot End'),
'variety_edit' => t('Edit Timeslot'),
'variety_session_list' => t('List Sessions'),
'variety_session_add' => t('Add Session'),
);
$result = db_query("SELECT * from {booking_variety_times}");
foreach($result as $data)
{
$options[$data->tid] = array
(
'tid' => $data->tid,
'booking_variety_time_descrip' => $data->booking_variety_time_descrip,
'booking_variety_status' => $data->booking_variety_status,
'booking_variety_start' => date("Y-m-d H:i", $data->booking_variety_start),
'booking_variety_end' => date("Y-m-d H:i", $data->booking_variety_end),
'variety_edit' => l('Edit Timeslot', t('admin/config/booking/variety/!tid/edit', array('!tid' => $data->tid))),
'variety_session_list' => l('List Sessions', t('admin/config/booking/variety/!tid/session/list', array('!tid' => $data->tid))),
'variety_session_add' => l('Add Session', t('admin/config/booking/variety/!tid/session/create', array('!tid' => $data->tid))),
);
}
$form['table'] = array (
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#multiple' => false,
);
return array (
'form' => $form,
);
}
/*
function booking_variety_admin_submit($form, &$form_state)
{
}
*/
function booking_variety_timeslot_form($node, &$form_state, $create, $editid = 0)
{
global $event;
$form = array ();
$prefix = "<p>Add a new variety session timeslot for the bookings module.</p>";
if ($create == true)
{
$data = $node;
}
else
{
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $editid)) {
drupal_set_message("Error: Invalid variety ID supplied. Unable to update variety session information.", 'error', FALSE);
drupal_goto('admin/config/booking/variety');
return "";
}
$data = db_select ('booking_variety_times', 'v')
->condition('v.tid', $editid, '=')
->fields('v')
->execute()
->fetchObject();
$prefix = t("<p>Update the !event variety session details.</p>", array('!event' => $event->booking_eventname));
//add this to the form in a hidden field so we can update the right event
$form['tid'] = array (
'#type' => 'hidden',
'#value' => $editid,
);
}
$form['booking_variety_time_descrip'] = array (
'#type' => 'textfield',
'#title' => t('The name of this variety session timeslot'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_time_descrip) ? $data->booking_variety_time_descrip : '',
);
$form['booking_variety_status'] = array(
'#type' => 'checkbox',
'#title' => t('Make this variety session timeslot active'),
'#default_value' => !empty($data->booking_variety_status) ? $data->booking_variety_status : '',
);
$form['booking_variety_start'] = array(
'#type' => 'date_select',
'#title' => t('When will this variety session start'),
'#default_value' => empty($data->booking_variety_start) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_start),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
);
$form['booking_variety_end'] = array(
'#type' => 'date_select',
'#title' => t('When will this variety session end?'),
'#default_value' => empty($data->booking_variety_end) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_end),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
);
if ($create == true)
{
$form['submit'] = array
(
'#type' => 'submit',
'#value' => t('Create'),
);
} else {
$form['Update'] = array
(
'#type' => 'submit',
'#value' => t('Update'),
);
$form['Delete'] = array
(
'#type' => 'submit',
'#value' => t('Delete'),
);
}
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
function booking_variety_timeslot_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
if ($form_state['values']['op'] == 'Create')
{
db_insert('booking_variety_times')
->fields(array(
'booking_eventid' => $event->eid,
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_time_descrip' => $values['booking_variety_time_descrip'],
'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']),
'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']),
))
->execute();
}
elseif ($form_state['values']['op'] == 'Delete')
{
//verify that tid is a number
if (! preg_match('/^[0-9]+$/', $values['tid'])) {
drupal_set_message("Error: Invalid variety timeslot ID supplied. Unable to delete entry.", 'error', FALSE);
return "";
}
$num_deleted = db_delete('booking_variety_times')
->condition('tid', $values['tid'])
->execute();
$message = t("Successfully deleted !num row(s), corresponding to variety session timeslot '!desc'",
array('!num' => $num_deleted, '!desc' => $values['booking_variety_time_descrip']));
drupal_set_message($message, $type = 'status');
}
else
{
//verify that booking_eid is a number
if (! preg_match('/^[0-9]+$/', $values['tid'])) {
drupal_set_message("Error: Invalid variety session timeslot ID supplied. Unable to update entry.", 'error', FALSE);
return "";
}
//update the event
db_update('booking_variety_times')
->fields(array (
'booking_eventid' => $event->eid,
'booking_variety_time_descrip' => $values['booking_variety_time_descrip'],
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']),
'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']),
))
->condition('tid', $values['tid'])
->execute();
}
$form_state['redirect'] = array('admin/config/booking/variety');
}
function booking_variety_create_session_form($node, &$form_state, $timeslot_id = 0)
{
global $event;
$form = array ();
$prefix = "<p>Add a new variety session to the specified variety session timeslot for the bookings module.</p>";
$data = $node;
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
drupal_set_message("Error: Invalid variety ID supplied. Unable to update variety session information.", 'error', FALSE);
drupal_goto('admin/config/booking/variety');
return "";
}
/*
$data = db_select ('booking_variety_times', 'v')
->condition('v.tid', $editid, '=')
->fields('v')
->execute()
->fetchObject();
*/
//add this to the form in a hidden field so we can update the right event
$form['tid'] = array (
'#type' => 'hidden',
'#value' => $timeslot_id,
);
$form['booking_variety_descrip'] = array (
'#type' => 'textfield',
'#title' => t('The name of the variety session to add to this timeslot'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_descrip) ? $data->booking_variety_descrip : '',
);
$form['booking_variety_status'] = array(
'#type' => 'checkbox',
'#title' => t('Make this variety session active?'),
'#default_value' => !empty($data->booking_variety_status) ? $data->booking_variety_status : '',
);
$form['booking_variety_maxsize'] = array (
'#type' => 'textfield',
'#title' => t('The maximum number of people permitted in this variety session'),
'#size' => 5,
'#maxlength' => 5,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_maxsize) ? $data->booking_variety_maxsize : '0',
);
$form['submit'] = array
(
'#type' => 'submit',
'#value' => t('Create'),
);
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
function booking_variety_create_session_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
db_insert('booking_variety_options')
->fields(array(
'booking_eventid' => $event->eid,
'booking_variety_timeslot_id' => $values['tid'],
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_descrip' => $values['booking_variety_descrip'],
'booking_variety_maxsize' => $values['booking_variety_maxsize'],
'booking_variety_regncount' => 0,
))
->execute();
$form_state['redirect'] = array('admin/config/booking/variety');
}
function booking_variety_list_session_form($node, &$form_state, $timeslot_id = 0)
{
global $event;
$form = array ();
$options = array ();
$data = $node;
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
drupal_set_message("Error: Invalid variety ID supplied. Unable to select variety session information.", 'error', FALSE);
drupal_goto('admin/config/booking/variety');
return "";
}
$prefix = t("<p>!link</p>",
array ('!link' => l('Add New Variety Session', "admin/config/booking/variety/$timeslot_id/session/create")));
$query = db_select ('booking_variety_options', 'v');
$query->join('booking_variety_times', 't', 'v.booking_variety_timeslot_id = t.tid');
$query->condition('v.booking_variety_timeslot_id', $timeslot_id, '=')
->fields('v')
->fields('t', array('booking_variety_time_descrip'));
$result = $query->execute();
//watchdog('booking', 'Variety session query: @info', array ('@info' => (string)$query));
$header = array (
'variety_timeslot' => t('Variety Timeslot'),
'booking_variety_descrip' => t('Variety Session Description'),
'booking_variety_status' => t('Status'),
'booking_variety_maxsize' => t('Maximum Capacity'),
'booking_variety_regncount' => t('Current Registration Count'),
'variety_edit' => t('Edit Session')
);
foreach($result as $data)
{
$options[$data->vid] = array
(
'variety_timeslot' => $data->booking_variety_time_descrip,
'booking_variety_descrip' => $data->booking_variety_descrip,
'booking_variety_status' => $data->booking_variety_status == 1 ? 1 : 0,
'booking_variety_maxsize' => $data->booking_variety_maxsize,
'booking_variety_regncount' => $data->booking_variety_regncount,
'variety_edit' => l('Edit Session', t('admin/config/booking/variety/session/!vid/edit', array('!vid' => $data->vid))),
);
}
$form['table'] = array (
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#multiple' => false,
);
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
function booking_variety_edit_session_form()
{
}
function booking_variety_regn_form($node, &$form_state)
{
global $event;
$form = array ();
$data = $node;
$timeslot_count = 0;
$query = db_query("SELECT * FROM {booking_variety_times} WHERE booking_eventid = :eid AND booking_variety_status = 1",
array(':eid' => $event->eid));
$form['booking_barcode'] = array (
'#type' => 'textfield',
'#title' => t('Barcode'),
'#description' => t('Enter the barcode from your lanyard'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_barcode) ? $data->booking_barcode : '',
);
//for each entry in the variety timeslot table, create a new form select item
$result = db_query("SELECT * from {booking_variety_times}");
foreach($query as $timeslot)
{
//reset the array
$options = array ();
$options[''] = '';
//query for variety sessions in the timeslot
$session_query = db_query("SELECT * from {booking_variety_options} WHERE booking_variety_timeslot_id = :id AND booking_variety_status = 1",
array(':id' => $timeslot->tid));
//add all the sessions to the select list
foreach($session_query as $session)
{
$options[$session->vid] = $session->booking_variety_descrip;
}
//create the form element for this timeslot
$form['select-variety-' . $timeslot_count] = array(
'#type' => 'select',
'#title' => t('Variety Session: ' . $timeslot->booking_variety_time_descrip),
'#required' => TRUE,
'#default_value' => '',
'#options' => $options,
);
$timeslot_count++;
}
$form['submit'] = array
(
'#type' => 'submit',
'#value' => t('Submit'),
);
return array (
'form' => $form,
);
}

914
booking.variety_admin.inc Normal file
View File

@@ -0,0 +1,914 @@
<?php
/**
* @file
* Admin pages for configuring a variety session
* NOTE: This feature is not complete and probably never will be
*/
function booking_variety_admin() {
global $event;
//see http://www.jaypan.com/blog/themeing-drupal-7-forms-tables-checkboxes-or-radios
// tableselect with text fields http://drupal.stackexchange.com/questions/75950/tableselect-with-textfields/82763#82763
// inline edit buttons http://drupal.stackexchange.com/questions/31942/how-do-i-add-an-edit-button-on-each-row-of-a-tableselect-form-element
// tabledrag example http://dropbucket.org/node/204
$form = array();
$options = array();
$query = db_select('booking_variety_timeslots', 't');
$query->leftJoin('booking_event', 'e', 't.booking_eventid = e.eid');
$query->fields('t')
->fields('e', array('eid', 'booking_eventname'));
$result = $query->execute();
$header = array (
'eid' => t('Event'),
'tid' => t('Timeslot ID'),
'booking_variety_time_descrip' => t('Description'),
'booking_variety_status' => t('Status'),
'booking_variety_start' => t('Timeslot Start'),
'booking_variety_end' => t('Timeslot End'),
'variety_edit' => t('Edit Timeslot'),
'variety_session_list' => t('List Sessions'),
'variety_session_add' => t('Add Session'),
'variety_session_csv' => t('CSV Report'),
);
foreach($result as $data) {
$options[$data->tid] = array (
'eid' => $data->booking_eventname,
'tid' => $data->tid,
'booking_variety_time_descrip' => $data->booking_variety_time_descrip,
'booking_variety_status' => $data->booking_variety_status == 1 ? "Enabled" : "Disabled",
'booking_variety_start' => date("Y-m-d H:i", $data->booking_variety_start),
'booking_variety_end' => date("Y-m-d H:i", $data->booking_variety_end),
'variety_edit' => l('Edit Timeslot', t('admin/booking/variety/!tid/edit', array('!tid' => $data->tid))),
'variety_session_list' => l('List Sessions', t('admin/booking/variety/!tid/session/list', array('!tid' => $data->tid))),
'variety_session_add' => l('Add Session', t('admin/booking/variety/!tid/session/create', array('!tid' => $data->tid))),
'variety_session_csv' => l('CSV Report', t('admin/booking/variety/!tid/csv', array('!tid' => $data->tid))),
);
}
$form['table'] = array (
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#multiple' => false,
);
return array (
'form' => $form,
);
}
/**
* Function to add a new variety session timeslot
*/
function booking_variety_timeslot_form($node, &$form_state, $create, $editid = 0) {
global $event;
$form = array();
$prefix = t("<p>Add a new variety session timeslot for !event variety sessions.</p>", array('!event' => $event->booking_eventname));
if ($create == true) {
$data = $node;
}
else {
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $editid)) {
drupal_set_message("Error: Invalid variety ID supplied. Unable to update variety session information.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
$data = db_select ('booking_variety_timeslots', 'v')
->condition('v.tid', $editid, '=')
->fields('v')
->execute()
->fetchObject();
$prefix = t("<p>Update the !event variety session details.</p>", array('!event' => $event->booking_eventname));
//add this to the form in a hidden field so we can update the right event
$form['tid'] = array (
'#type' => 'hidden',
'#value' => $editid,
);
}
$form['booking_variety_time_descrip'] = array (
'#type' => 'textfield',
'#title' => t('The name of this variety session timeslot'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_time_descrip) ? $data->booking_variety_time_descrip : '',
);
$form['booking_variety_status'] = array(
'#type' => 'checkbox',
'#title' => t('Make this variety session timeslot active'),
'#default_value' => !empty($data->booking_variety_status) ? $data->booking_variety_status : '',
);
$form['booking_variety_start'] = array(
'#type' => 'date_select',
'#title' => t('When will this variety session start'),
'#default_value' => empty($data->booking_variety_start) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_start),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
);
$form['booking_variety_end'] = array(
'#type' => 'date_select',
'#title' => t('When will this variety session end?'),
'#default_value' => empty($data->booking_variety_end) ? date("Y-m-d H:i:s") : date("Y-m-d H:i:s", $data->booking_variety_end),
'#date_format' => 'd/m/Y H:i',
'#date_label_position' => 'within',
'#date_year_range' => '0:+5'
);
if ($create == true) {
$form['submit'] = array (
'#type' => 'submit',
'#value' => t('Create'),
);
}
else {
$form['Update'] = array (
'#type' => 'submit',
'#value' => t('Update'),
);
$form['Delete'] = array (
'#type' => 'submit',
'#value' => t('Delete'),
);
}
return array(
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
/**
* Function to submit data for a new variety session timeslot
*/
function booking_variety_timeslot_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
if ($form_state['values']['op'] == 'Create') {
db_insert('booking_variety_timeslots')
->fields(array(
'booking_eventid' => $event->eid,
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_time_descrip' => $values['booking_variety_time_descrip'],
'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']),
'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']),
))
->execute();
}
elseif ($form_state['values']['op'] == 'Delete') {
//verify that tid is a number
if (! preg_match('/^[0-9]+$/', $values['tid'])) {
drupal_set_message("Error: Invalid variety timeslot ID supplied. Unable to delete entry.", 'error', FALSE);
return "";
}
$num_deleted = db_delete('booking_variety_timeslots')
->condition('tid', $values['tid'])
->execute();
$message = t("Successfully deleted !num row(s), corresponding to variety session timeslot '!desc'",
array('!num' => $num_deleted, '!desc' => $values['booking_variety_time_descrip']));
drupal_set_message($message, $type = 'status');
}
else {
//verify that booking_eid is a number
if (! preg_match('/^[0-9]+$/', $values['tid'])) {
drupal_set_message("Error: Invalid variety session timeslot ID supplied. Unable to update entry.", 'error', FALSE);
return "";
}
//update the event
db_update('booking_variety_timeslots')
->fields(array (
'booking_eventid' => $event->eid,
'booking_variety_time_descrip' => $values['booking_variety_time_descrip'],
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_start' => _datetime_array_to_ts($values['booking_variety_start']),
'booking_variety_end' => _datetime_array_to_ts($values['booking_variety_end']),
))
->condition('tid', $values['tid'])
->execute();
}
$form_state['redirect'] = array('admin/booking/variety');
}
/**
* Function to create or edit a variety session
*/
function booking_variety_create_session_form($node, &$form_state, $create = TRUE, $timeslot_id = 0, $session_id = 0) {
global $event;
$form = array();
$prefix = "";
//add this to the form in a hidden field so we can update the right event
$form['tid'] = array (
'#type' => 'hidden',
'#value' => $timeslot_id,
);
if ($create == TRUE) {
$data = $node;
$prefix = "<p>Add a new variety session to the specified variety session timeslot for the bookings module.</p>";
}
else {
//verify that $timeslot_id is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
drupal_set_message("Error: Invalid timeslot ID supplied. Unable to update specified variety session.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
//verify that $session_id is a number
if (! preg_match('/^[0-9]+$/', $session_id)) {
drupal_set_message("Error: Invalid session ID supplied. Unable to update specified variety session.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
$prefix = t("<p>Update the variety session defintion.</p>");
$data = db_query("SELECT * FROM {booking_variety_sessions} WHERE vid = :id", array(':id' => $session_id))
->fetchObject();
//add this to the form in a hidden field so we can update the right variety session
$form['booking_session_id'] = array(
'#type' => 'hidden',
'#value' => $session_id,
);
}
//define the form for variety session configuration if we're not deleting a session
if(!isset($form_state['storage']['confirm'])) {
$form[] = array (
'first_heading' => array(
'#type' => 'markup',
'#markup' => $prefix,
),
);
$form['booking_variety_descrip'] = array (
'#type' => 'textfield',
'#title' => t('The name of the variety session to add to this timeslot'),
'#size' => 60,
'#maxlength' => 150,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_descrip) ? $data->booking_variety_descrip : '',
);
$form['booking_variety_status'] = array(
'#type' => 'checkbox',
'#title' => t('Make this variety session active?'),
'#default_value' => !empty($data->booking_variety_status) ? $data->booking_variety_status : '',
);
$form['booking_variety_maxsize'] = array (
'#type' => 'textfield',
'#title' => t('The maximum number of people permitted in this variety session'),
'#size' => 5,
'#maxlength' => 5,
'#required' => TRUE,
'#default_value' => !empty($data->booking_variety_maxsize) ? $data->booking_variety_maxsize : '0',
);
if ($create == true) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create Session'),
);
}
else {
$form['Update'] = array(
'#type' => 'submit',
'#value' => t('Update Session'),
);
$form['Delete'] = array(
'#type' => 'submit',
'#value' => t('Delete Session'),
);
}
return array (
'form' => $form,
);
} //end checking for delete confirmation
else {
return confirm_form($form, "Are you sure you wish to delete variety session definition with id " . $session_id . "?",
current_path(), NULL, "Delete Session");
}
}
/**
* Function submit data for a variety session timeslot
*/
function booking_variety_create_session_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
$timeslot_id = $values['tid'];
//verify that $timeslot_id is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
$redirect_path = "admin/booking/variety";
}
else {
$redirect_path = "admin/booking/variety/$timeslot_id/session/list";
}
//if we're deleting, add the confirmation to the form if it hasn't been defined yet
if($form_state['values']['op'] == 'Delete Session' && (!isset($form_state['storage']['confirm']))) {
//watchdog('booking_debug', "<pre>Variety session deletion confirmation being set:\n@info</pre>", array('@info' => print_r( $form_state, true)));
$form_state['storage']['confirm'] = TRUE;
$form_state['rebuild'] = TRUE;
}
elseif ($form_state['values']['op'] == 'Delete Session') {
//delete the variety session
watchdog('booking', "Deleting variety session ID !sid", array('!sid' => $values['booking_session_id']));
db_delete('booking_variety_sessions')
->condition('vid', $values['booking_session_id'])
->execute();
//TODO : Remove this variety session from anyone registered for it
drupal_set_message('Deleted variety session id ' . $values['booking_session_id'] );
$form_state['redirect'] = $redirect_path;
}
elseif ($form_state['values']['op'] == 'Update Session') {
$result = db_update('booking_variety_sessions')
->fields(array(
'booking_eventid' => $event->eid,
'booking_variety_descrip' => $values['booking_variety_descrip'],
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_maxsize' => $values['booking_variety_maxsize'],
))
->condition('vid', $values['booking_session_id'] )
->execute();
drupal_set_message('Updated variety session id ' . $values['booking_session_id'] );
$form_state['redirect'] = $redirect_path;
}
elseif ($form_state['values']['op'] == 'Create Session') {
db_insert('booking_variety_sessions')
->fields(array(
'booking_eventid' => $event->eid,
'booking_variety_timeslot_id' => $values['tid'],
'booking_variety_status' => $values['booking_variety_status'] == 1 ? 1 : 0,
'booking_variety_descrip' => $values['booking_variety_descrip'],
'booking_variety_maxsize' => $values['booking_variety_maxsize'],
'booking_variety_regncount' => 0,
))
->execute();
drupal_set_message('Created new variety session definition');
$form_state['redirect'] = $redirect_path;
}
}
/**
* Function to list all variety sessions for specified timeslot
*/
function booking_variety_list_session_form($node, &$form_state, $timeslot_id = 0)
{
global $event;
$form = array();
$options = array();
$data = $node;
//verify that $editid is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
drupal_set_message("Error: Invalid variety ID supplied. Unable to select variety session information.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
$prefix = t("<p>!link</p>",
array('!link' => l('Add New Variety Session', "admin/booking/variety/$timeslot_id/session/create")));
$query = db_select ('booking_variety_sessions', 'v');
$query->join('booking_variety_timeslots', 't', 'v.booking_variety_timeslot_id = t.tid');
$query->condition('v.booking_variety_timeslot_id', $timeslot_id, '=')
->fields('v')
->fields('t', array('booking_variety_time_descrip'));
$result = $query->execute();
//watchdog('booking', 'Variety session query: @info', array ('@info' => (string)$query));
$header = array (
'variety_timeslot' => t('Variety Timeslot'),
'booking_variety_descrip' => t('Variety Session Description'),
'booking_variety_status' => t('Status'),
'booking_variety_maxsize' => t('Maximum Capacity'),
'booking_variety_regncount' => t('Current Registration Count'),
'variety_edit' => t('Edit Session')
);
foreach($result as $data) {
$options[$data->vid] = array (
'variety_timeslot' => $data->booking_variety_time_descrip,
'booking_variety_descrip' => $data->booking_variety_descrip,
'booking_variety_status' => $data->booking_variety_status == 1 ? 'Active' : 'Inactive',
'booking_variety_maxsize' => $data->booking_variety_maxsize,
'booking_variety_regncount' => $data->booking_variety_regncount,
'variety_edit' => l('Edit Session', t('admin/booking/variety/!tid/session/!vid/edit',
array('!tid' => $timeslot_id, '!vid' => $data->vid))),
);
}
$form['table'] = array (
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#multiple' => false,
);
return array (
'first_para' => array (
'#type' => 'markup',
'#markup' => $prefix,
),
'form' => $form,
);
}
/**
* Function to generate table listing all variety session registrations
*/
function booking_variety_sessions_view_summary() {
global $event;
$output = "";
$header = array('First Name', 'Last Name');
$rows = array();
$attributes = array('style' => 'max-width:100%');
//get variety session timeslot definitions
$timeslot_query = db_select('booking_variety_timeslots', 't');
$timeslot_query->condition('t.booking_eventid', $event->eid, '=')
->fields('t')
->orderBy('t.booking_variety_start');
$timeslot_list = $timeslot_query->execute()->fetchAllAssoc('tid');
//watchdog('booking_debug', "<pre>Variety Session Report timeslots:\n@info</pre>", array('@info' => print_r( $timeslot_list, true)));
//get vareity session definitions
$sessions_query = db_query("SELECT * FROM {booking_variety_sessions} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$sessions = $sessions_query->fetchAllAssoc('vid');
//watchdog('booking_debug', "<pre>Variety Session Report sessions:\n@info</pre>", array('@info' => print_r( $sessions, true)));
foreach ($timeslot_list as $timeslot) {
$header[] = $timeslot->booking_variety_time_descrip;
}
// Add a link at the end to edit a variety session registration
$header[] = "Edit Session Registrations";
$person_query = db_query("SELECT * FROM {booking_person_view} WHERE booking_status = 1 " .
" ORDER BY booking_lastname, booking_firstname")->fetchAllAssoc('nid');
//loop through each matching person
foreach ($person_query as $person) {
//add the name to an array for this line
$newline = array($person->booking_firstname, $person->booking_lastname);
$session_ids = drupal_json_decode($person->booking_variety_ids);
foreach ($timeslot_list as $timeslot) {
if (isset($session_ids[$timeslot->tid])) {
//get details of the person's variety session for this timeslot
$vid = $session_ids[$timeslot->tid];
//watchdog('booking_debug', 'Person @nid in timeslot @tid registered for session id @vid', array(
// '@nid' => $person->nid, '@tid' => $timeslot->tid, '@vid' => $vid,
//));
// in case the person is somehow registered for a session that no longer exists
if (isset($sessions[$vid])) {
$text = $sessions[$vid]->booking_variety_descrip;
}
else {
$text = "";
}
$newline[] = $text;
}
else {
$newline[] = "";
}
} //end iterate variety session timeslot list
$newline[] = l('Edit', t('admin/booking/variety/registration/!nid/edit', array('!nid' => $person->nid)));
//add the line to the array of rows
$rows[] = $newline;
} //end iterate person list
//output everything
$output .= t("<h3>!event Variety Session Registrations</h3>", array('!event' => $event->booking_eventname));
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => $attributes));
return $output;
}
/**
* Function to generate a CSV file listing the session membership for the specified variety session timeslot
*/
function booking_varietysessions_csv_report($timeslot_id) {
global $event;
$data = array();
$rows = array();
module_load_include('php', 'booking', 'libraries/xlsxwriter.class');
//verify that $timeslot_id is a number
if (! preg_match('/^[0-9]+$/', $timeslot_id)) {
drupal_set_message("Error: Invalid variety session timeslot ID '" . $timeslot_id . "' supplied.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
//retrieve the sessions for the specified timeslot
$db_and = db_and();
//$db_and->condition('v.booking_eventid', $event->eid, '=');
$db_and->condition('v.booking_variety_timeslot_id', $timeslot_id, '=');
$variety_sessions = db_select('booking_variety_sessions', 'v')
->condition($db_and)
->fields('v')
->execute()
->fetchAllAssoc('vid');
//watchdog('booking_debug', 'booking_varietysessions_csv_report variety sessions: <pre>@info</pre>', array('@info' => print_r( $variety_sessions, true)));
if (! $variety_sessions) {
drupal_set_message("Error: Could not find matching variety session timeslot. Unable to view session membership.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
//set options for the CSV file
$csv = '';
$delimiter = ',';
$enclosure = '"';
$encloseAll = false;
$nullToMysqlNull = true;
$delimiter_esc = preg_quote($delimiter, '/');
$enclosure_esc = preg_quote($enclosure, '/');
// List of style options at https://github.com/mk-j/PHP_XLSXWriter/issues/198
$header_style = array( 'border'=>'bottom','border-style'=>'thin', 'border-color'=>'#000000',
'valign'=>'top', 'font-style' => 'bold','font' => 'Calibri');
$row_style = array('font' => 'Calibri');
//get the list of variety session memberships
$session_members_query = db_query("SELECT r.*, p.* FROM {booking_variety_regn} r
inner join {booking_person} p on p.nid = r.booking_person_nid
WHERE p.booking_eventid = :eid ORDER BY r.rid",
array(':eid' => $event->eid));
$session_members = $session_members_query->fetchAll();
// Check if we had no data added, that means there were no people in this study group
if (! $session_members) {
drupal_set_message("Error: Variety Session timeslot $timeslot_id has no members assigned.", 'error', FALSE);
drupal_goto('admin/booking/variety');
return "";
}
//watchdog('booking_debug', 'booking_varietysessions_csv_report session members: <pre>@info</pre>', array('@info' => print_r( $session_members, true)));
// Organise people by session ID
foreach ($session_members as $member) {
$session_ids = drupal_json_decode($member->booking_variety_ids);
//watchdog('booking_debug', 'booking_varietysessions_csv_report person session ids: <pre>@info</pre>', array('@info' => print_r( $session_ids, true)));
//get the session id that matches our timeslot if it exists
if (isset($session_ids[$timeslot_id])) {
$sid = $session_ids[$timeslot_id];
if (! isset($data[$sid])) {
$data[$sid] = array();
}
//add the spaces and put this element in the right array
$text = array($member->booking_firstname, $member->booking_lastname);
$data[$sid][] = implode(' ', $text);
}
}
//watchdog('booking_debug', "<pre>Study Group CSV Report\n@info</pre>", array('@info' => print_r( $data_array, true)));
// Calculate column headings and spreadsheet layout
$header_array = array_keys($data);
$maximums = array();
$column_headings = array();
foreach ($header_array as $column) {
$maximums[] = count($data[$column]);
//make the column headings a bit more user friendly
$heading = $variety_sessions[$column]->booking_variety_descrip;
//enclose $heading if necessary
//if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $heading ) ) {
// $heading = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $heading) . $enclosure;
//}
// Adjusted for excel, assume each column is just a string
//$column_headings[] = array($heading => 'string');
$column_headings[$heading] = 'string';
}
watchdog('booking_debug', "<pre>Variety session spreadsheet columns\n@info</pre>",
array('@info' => print_r( $column_headings, true)));
// Calculate each row based on column headings
for ($i = 0; $i < max($maximums); $i++) {
$output = array();
foreach ($header_array as $column) {
$field = isset($data[$column][$i]) ? $data[$column][$i] : '';
//enclose $field if necessary
//if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
// $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure;
//}
//else {
$output[] = $field;
//}
} //loop through columns
$rows[] = $output;
//$row = implode($delimiter, $output) . "\n";
//$csv .= $row;
}
watchdog('booking_debug', "<pre>Variety session spreadsheet rows\n@info</pre>",
array('@info' => print_r( $rows, true)));
// Create headers for Excel spreadsheet
$filename = 'bookings-timeslot-' . $timeslot_id . '-variety-sessions-' . format_date(time(), 'custom', 'Y-m-d-His') . ".xlsx";
header('Content-disposition: attachment; filename="'.XLSXWriter::sanitize_filename($filename).'"');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$sheetname = "Variety Session " . $timeslot_id;
$writer = new XLSXWriter();
$writer->setAuthor($event->booking_eventname);
//Add the header row
$writer->writeSheetHeader($sheetname, $column_headings, $header_style);
//Add the data
foreach($rows as $row) {
$writer->writeSheetRow($sheetname, $row, $row_style);
}
$writer->writeToStdOut();
exit(0);
}
/**
* Build the admin form for editing variety session registrations
*/
function booking_variety_regn_edit_form($node, &$form_state, $nid)
{
global $event;
$form = array();
$data = $node;
$redirect_path = "admin/booking/variety/report";
//verify that $variety_regn_id is a number
if (! preg_match('/^[0-9]+$/', $nid)) {
drupal_set_message("Error: Invalid variety session registration ID supplied. Unable to update variety session registration for user.", 'error', FALSE);
drupal_goto($redirect_path);
return "";
}
$person = db_query("SELECT * FROM {booking_person_view} WHERE nid = :nid",
array(':nid' => $nid))->fetchObject();
if (! $person) {
drupal_set_message("Error: Could not find matching person. Unable to edit variety session registrations.", 'error', FALSE);
drupal_goto($redirect_path);
return "";
}
$session_ids = drupal_json_decode($person->booking_variety_ids);
$prefix = t("<h3>Edit variety session registration for !first !last.<br /></h3>",
array('!first' => $person->booking_firstname, '!last' => $person->booking_lastname));
// Query the variety timeslot table so we know how many select elements to create
$timeslot_query = db_select('booking_variety_timeslots', 'v');
$timeslot_query->condition('v.booking_eventid', $event->eid, '=')
->fields('v')
->orderBy('v.booking_variety_start');
$timeslot_result = $timeslot_query->execute();
// --- Form starts here ---
//add the person nid to the form in a hidden field so we can update the right person later
$form['nid'] = array (
'#type' => 'hidden',
'#value' => $nid,
);
//define the form for variety session configuration if we're not deleting a session
if(!isset($form_state['storage']['confirm'])) {
$form[] = array (
'first_heading' => array(
'#type' => 'markup',
'#markup' => $prefix,
),
);
$form['variety-sessions'] = array(
'#type' => 'fieldset',
'#title' => 'Select Variety Sessions',
'#prefix' => '<div id="booking_variety_session_fieldset_wrapper">',
'#suffix' => '</div>'
);
//for each entry in the variety timeslot table, create a new form select item
foreach($timeslot_result as $timeslot) {
$fieldname = 'select-variety-' . $timeslot->tid;
$default = isset($session_ids[$timeslot->tid]) ? $session_ids[$timeslot->tid] : '--';
$default_value = isset($form_state['values'][$fieldname]) ? $form_state['values'][$fieldname] : $default;
//create the form element for this timeslot
$form['variety-sessions'][$fieldname] = array(
'#type' => 'select',
'#title' => t('Variety Session: ' . $timeslot->booking_variety_time_descrip),
'#required' => TRUE,
'#default_value' => $default_value,
'#options' => _booking_get_variety_timeslot_options($timeslot->tid),
);
}
$form['Update'] = array(
'#type' => 'submit',
'#value' => t('Update Session Registration'),
);
$form['Delete'] = array(
'#type' => 'submit',
'#value' => t('Delete Session Registration'),
);
return array (
'form' => $form,
);
} //end checking for delete confirmation
else {
return confirm_form($form, "Are you sure you wish to delete all variety session registrations for person id " . $nid . "?",
current_path(), NULL, "Delete Session Registration");
}
}
/**
* Function submit data for editing a variety session registration for a person
*/
function booking_variety_regn_edit_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
$booking_variety_ids = array();
$redirect_path = "admin/booking/variety/report";
//get a list of timeslot IDs from matching form values
$variety_timeslot_ids = preg_filter('/^select-variety-(\d+)/', '$1', array_keys( $values ));
//build an associative array based on selections
foreach ($variety_timeslot_ids as $id) {
$selected_session_id = $values['select-variety-' . $id];
// Don't try and check availablity for a select element that is still on the default value
if ($selected_session_id == 0) {
continue;
}
//store the selected variety sessions in an array of IDs
$booking_variety_ids[$id] = $selected_session_id;
}
watchdog('booking_debug', "<pre>Variety session IDs from edit form:\n@info</pre>", array('@info' => print_r( $booking_variety_ids, true)));
// Get the previous variety session IDs so we can check for changes
$person = db_query("SELECT * FROM {booking_person_view} WHERE nid = :nid",
array(':nid' => $values['nid']))->fetchObject();
$previous_variety_ids = drupal_json_decode($person->booking_variety_ids);
//if we're deleting, add the confirmation to the form if it hasn't been defined yet
if($form_state['values']['op'] == 'Delete Session Registration' && (!isset($form_state['storage']['confirm']))) {
//watchdog('booking_debug', "<pre>Variety session registration deletion confirmation being set:\n@info</pre>", array('@info' => print_r( $form_state, true)));
$form_state['storage']['confirm'] = TRUE;
$form_state['rebuild'] = TRUE;
}
elseif ($form_state['values']['op'] == 'Delete Session Registration') {
//delete the variety session
watchdog('booking', "Deleting variety session registration for person ID !nid", array('!nid' => $values['nid']));
//decremement regn count for this person's variety sessions
foreach ($previous_variety_ids as $previous_tid => $previous_sid) {
watchdog('booking_debug', 'Person @nid in timeslot @tid is no longer registered for any variety sessions so reducing count for @vid by 1', array(
'@nid' => $values['nid'], '@tid' => $previous_tid, '@vid' => $previous_sid,
));
// reduce regn count for old session
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount - :count', array(':count' => 1))
->condition('vid', $previous_sid)
->execute();
}
//delete this person's entry in the session registration table
db_delete('booking_variety_regn')
->condition('booking_person_nid', $values['nid'])
->execute();
drupal_set_message('Deleted variety session registration for person id ' . $values['nid'] );
$form_state['redirect'] = $redirect_path;
}
elseif ($form_state['values']['op'] == 'Update Session Registration') {
// iterate over the new list comparing to the old list
foreach ($booking_variety_ids as $new_tid => $new_sid) {
//check if there was a previous session ID for this person in this timeslot
if (! isset($previous_variety_ids[$new_tid])) {
watchdog('booking_debug', 'Person @nid in timeslot @tid had no previous session id registered but is now @new.', array(
'@nid' => $values['nid'], '@tid' => $new_tid, '@new' => $new_sid));
// increase regn count for new session
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount + :count', array(':count' => 1))
->condition('vid', $new_sid)
->execute();
}
else {
$previous_sid = $previous_variety_ids[$new_tid];
//compare session id in this timeslot to the previous value
if ($new_sid != $previous_sid) {
watchdog('booking_debug', 'Person @nid in timeslot @tid previously registered for session id @vid but new value is @new', array(
'@nid' => $values['nid'], '@tid' => $new_tid, '@vid' => $previous_sid, '@new' => $new_sid));
// if variety session has changed then update the counts for old and new
if ($new_sid != $previous_sid) {
// reduce regn count for old session
watchdog('booking_debug', 'Person @nid in timeslot @tid is no longer registered for variety session @vid so reducing count by 1', array(
'@nid' => $values['nid'], '@tid' => $new_tid, '@vid' => $previous_sid));
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount - :count', array(':count' => 1))
->condition('vid', $previous_sid)
->execute();
// increase regn count for new session
watchdog('booking_debug', 'Person @nid in timeslot @tid is now registered for variety session @vid so increasing count by 1', array(
'@nid' => $values['nid'], '@tid' => $new_tid, '@vid' => $new_sid));
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount + :count', array(':count' => 1))
->condition('vid', $new_sid)
->execute();
}
}
else {
watchdog('booking_debug', 'Person @nid in timeslot @tid has not changed variety session @vid', array(
'@nid' => $values['nid'], '@tid' => $new_tid, '@vid' => $new_sid));
}
}
}
//iterate over the old list comparing to the new list in case there are regn counts we need to decrease
if (isset($previous_variety_ids)) {
foreach ($previous_variety_ids as $previous_tid => $previous_sid) {
if (! isset($booking_variety_ids[$previous_tid])) {
watchdog('booking_debug', 'Person @nid in timeslot @tid is no longer registered for a variety session so reducing count for @vid by 1', array(
'@nid' => $values['nid'], '@tid' => $previous_tid, '@vid' => $previous_sid,
));
// reduce regn count for old session
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount - :count', array(':count' => 1))
->condition('vid', $previous_sid)
->execute();
}
}
}
// See if this person ever had a variety session registration
$update_or_insert_check = db_query("SELECT * FROM {booking_variety_regn} " .
"WHERE booking_person_nid = :nid",
array(':nid' => $values['nid'],
))->fetchObject();
if (! $update_or_insert_check) {
// create new variety session registration information for this person
$result = db_insert('booking_variety_regn')
->fields(array(
'booking_person_nid' => $values['nid'],
'booking_variety_ids' => drupal_json_encode($booking_variety_ids),
))
->execute();
watchdog('booking', "Created variety session registration for person ID !nid", array('!nid' => $values['nid']));
}
else {
// update the session registration information for this person
$result = db_update('booking_variety_regn')
->fields(array(
'booking_variety_ids' => drupal_json_encode($booking_variety_ids),
))
->condition('booking_person_nid', $values['nid'])
->execute();
watchdog('booking', "Updated variety session registration for person ID !nid", array('!nid' => $values['nid']));
}
// Finished, redirect to original table
$form_state['redirect'] = $redirect_path;
}
}

302
booking.variety_form.inc Normal file
View File

@@ -0,0 +1,302 @@
<?php
/**
* @file
* User facing page for booking into a variety session
* NOTE: This feature is not complete
*/
/**
* Build the user-facing variety session registration form
*/
function booking_variety_regn_form($node, &$form_state)
{
global $event;
$form = array();
$data = $node;
$markup_input = variable_get('booking_variety_regn_page');
$markup_html = token_replace($markup_input['value'], booking_define_tokens());
// Query the variety timeslot table
$timeslot_query = db_select('booking_variety_timeslots', 'v');
$timeslot_query->condition('v.booking_eventid', $event->eid, '=')
->fields('v')
->orderBy('v.booking_variety_start');
$result = $timeslot_query->execute();
$form['#prefix'] = '<div id="booking_variety_form_wrapper">';
$form['#suffix'] = '</div>';
$form['paragraph'] = array(
'#type' => 'markup',
'#markup' => $markup_html,
);
$form['identity'] = array(
'#type' => 'fieldset',
'#title' => 'Enter Your Details',
);
$form['identity']['booking_nid'] = array(
'#type' => 'textfield',
'#title' => t('Booking Number'),
'#description' => t('Please enter your booking number from your lanyard.'),
'#size' => 60,
'#required' => TRUE,
'#default_value' => !empty($data->booking_nid) ? $data->booking_nid : '',
//'#attributes' => array('inputmode' => 'numeric', 'pattern' =>'[0-9]*'),
'#attributes' => array(' type' => 'number', ' pattern' =>'[0-9]*'),
//'#ajax' => array(
// 'event' => 'change',
// 'wrapper' => 'booking_variety_form_wrapper',
// 'callback' => 'booking_variety_session_form_callback',
//),
);
$form['identity']['booking_lastname'] = array(
'#type' => 'textfield',
'#title' => t('Surname'),
'#description' => t('Please enter your last name as it appeared when you registered.'),
'#size' => 60,
'#required' => TRUE,
'#default_value' => !empty($data->booking_lastname) ? $data->booking_lastname : '',
'#ajax' => array(
'event' => 'change',
'wrapper' => 'booking_variety_form_wrapper',
'callback' => 'booking_variety_session_form_callback',
),
);
$form['variety-sessions'] = array(
'#type' => 'fieldset',
'#title' => 'Select Variety Sessions',
//'#attributes' => array('class' => array('element-hidden')),
//'#prefix' => '<div id="booking_variety_session_fieldset_wrapper">',
//'#suffix' => '</div>'
);
$form['identity']['booking_feedback_wrapper'] = array(
'#markup' => '<div id="booking_feedback_wrapper"></div>',
);
//for each entry in the variety timeslot table, create a new form select item
foreach($result as $timeslot) {
$fieldname = 'select-variety-' . $timeslot->tid;
//create the form element for this timeslot
$form['variety-sessions'][$fieldname] = array(
'#type' => 'select',
'#title' => t('Variety Session: ' . $timeslot->booking_variety_time_descrip),
'#required' => TRUE,
'#default_value' => isset($form_state['values'][$fieldname]) ? $form_state['values'][$fieldname] : 0,
'#options' => _booking_get_variety_timeslot_options($timeslot->tid),
//'#prefix' => '<div id="booking_variety_session_' . $timeslot->tid . '_wrapper">',
//'#suffix' => '</div>',
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return array (
'form' => $form,
);
}
/**
* Function to calculate available variety sessions for ajax enabled form booking_variety_regn_form()
* @param $timeslot_id - the timeslot ID to query
* @return array containing the variety sessions for specified timeslot that still have capacity
*/
function _booking_get_variety_timeslot_options($timeslot_id) {
$session_options = array();
$session_options[] = "--";
$session_query = db_query("SELECT * FROM {booking_variety_sessions} WHERE booking_variety_timeslot_id = :tid AND booking_variety_status = 1",
array(':tid' => $timeslot_id));
// Only add sessions that aren't full to the return result
foreach($session_query as $session) {
$available_spots = $session->booking_variety_maxsize - $session->booking_variety_regncount;
if ($available_spots > 0) {
$session_options[$session->vid] = $session->booking_variety_descrip . " [" . $available_spots . " spots left]";
}
}
//watchdog('booking_debug', "<pre>Variety Session Options:\n@info</pre>", array('@info' => print_r( $session_options, true)));
return $session_options;
}
/**
* Callback function to rebuild the variety session fieldset
*/
function booking_variety_session_form_callback($form, &$form_state) {
global $event;
$data = $form_state['input'];
//$form['form']['variety-sessions']['booking_feedback_wrapper']['#markup'] = '<div id="booking_feedback_wrapper">Test</div>';
//return $form['form']['variety-sessions'];
if (isset($data['booking_nid']) && $data['booking_nid'] != '' && isset($data['booking_lastname']) && $data['booking_lastname'] != '') {
// Perform lookup on person to make sure it matches someone attending the current event
$db_and = db_and();
$db_and->condition('p.booking_eventid', $event->eid, '=');
$db_and->condition('p.booking_status', 1, '=');
$db_and->condition('p.nid', $data['booking_nid'], '=');
$db_and->condition('p.booking_lastname', $data['booking_lastname'], '=');
$query = db_select('booking_person', 'p');
$query->condition($db_and)
->fields('p');
$person = $query->execute()
->fetchObject();
// Update feedback based on query result
if (! $person) {
$form['form']['identity']['booking_feedback_wrapper']['#markup'] = '<div id="booking_feedback_wrapper" style="font-size: 0.85em;">User not found.</div>';
}
else {
$form['form']['identity']['booking_feedback_wrapper']['#markup'] = '<div id="booking_feedback_wrapper" style="font-size: 0.85em;">Verified user.</div>';
//$form['form']['variety-sessions']['#attributes']['class'] = '';
}
}
// Rebuild the form
$form_state['rebuild'] = TRUE;
return $form['form'];
}
/**
* Validate the submission for the user-facing variety session registration form
*/
function booking_variety_regn_form_validate($form, &$form_state) {
global $event;
$values = $form_state['input'];
//watchdog('booking_debug', 'booking_variety_regn_form_validate: <pre>@info</pre>', array('@info' => print_r( $form_state, true)));
// Don't run validation on ajax callback
if (isset($form_state['input']['_triggering_element_name'])) {
//watchdog('booking_debug', 'booking_variety_regn_form_validate: skipping due to ajax callback');
return;
}
// --- Check that the registration number is valid ---
//verify that user-entered data is a number
if (! preg_match('/^[0-9]+$/', $values['booking_nid'])) {
form_set_error('booking_nid', t('You have entered an invalid booking reference number.'));
}
// Perform lookup on barcode to make sure it matches someone attending the current event
$db_and = db_and();
$db_and->condition('p.booking_eventid', $event->eid, '=');
$db_and->condition('p.booking_status', 1, '=');
$db_and->condition('p.nid', $values['booking_nid'], '=');
$db_and->condition('p.booking_lastname', $values['booking_lastname'], '=');
$query = db_select('booking_person', 'p');
$query->condition($db_and)
->fields('p');
$person = $query->execute()
->fetchObject();
if (! $person) {
form_set_error('booking_nid', t('You have entered an invalid booking reference number or your surname does not match your registration details.'));
}
// --- Check that this person hasn't already registered for variety sessions
$prev_regn_query = db_select('booking_variety_regn', 'v')
->condition('v.booking_person_nid', $values['booking_nid'], '=')
->fields('v')
->execute();
if ($prev_regn_query->rowCount() > 0) {
form_set_error('booking_nid', t('You have already registered for variety sessions. Existing registration cannot be changed.'));
}
// --- Check there is still space available in the selected variety sessions ---
//get a list of timeslot IDs from matching form values
$variety_timeslot_ids = preg_filter('/^select-variety-(\d+)/', '$1', array_keys( $values ));
//query the sessions table
$sessions_query = db_query("SELECT * FROM {booking_variety_sessions} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$sessions = $sessions_query->fetchAllAssoc('vid');
//watchdog('booking_debug', 'booking_variety_regn_form_validate sessions query: <pre>@info</pre>', array('@info' => print_r( $sessions, true)));
//check there is still room
foreach ($variety_timeslot_ids as $id) {
$selected_session_id = $values['select-variety-' . $id];
// Don't try and check availablity for a select element that is still on the default value
if ($selected_session_id == 0) {
form_set_error('select-variety-' . $id, t('You have not selected a variety session.'));
continue;
}
$session = $sessions[$selected_session_id];
if ($session->booking_variety_regncount >= $session->booking_variety_maxsize) {
//watchdog('booking_debug', 'No room in session @id : @count is less than @size', array(
// '@id' => $selected_session_id, '@count' => $session->booking_variety_regncount,
// '@size' => $session->booking_variety_maxsize
//));
$form_state['rebuild'] = TRUE;
$form_state['flag'] = 1;
drupal_set_message('You have selected a session that is now full. Please try again.', 'error', FALSE);
}
}
}
/**
* Process the submission for the user-facing variety session registration form
*/
function booking_variety_regn_form_submit($form, &$form_state) {
global $event;
$values = $form_state['input'];
//watchdog('booking_debug', 'booking_variety_regn_form_submit: <pre>@info</pre>', array('@info' => print_r( $form_state, true)));
$booking_variety_ids = array();
//get a list of timeslot IDs from matching form values
$variety_timeslot_ids = preg_filter('/^select-variety-(\d+)/', '$1', array_keys( $values ));
//query the sessions table
$sessions_query = db_query("SELECT * FROM {booking_variety_sessions} WHERE booking_eventid = :eid",
array(':eid' => $event->eid));
$sessions = $sessions_query->fetchAllAssoc('vid');
foreach ($variety_timeslot_ids as $id) {
$selected_session_id = $values['select-variety-' . $id];
// Don't try and check availablity for a select element that is still on the default value
if ($selected_session_id == 0) {
continue;
}
//use an update query for the regncount field
//idea from https://api.drupal.org/comment/19374#comment-19374
db_update('booking_variety_sessions')
->expression('booking_variety_regncount', 'booking_variety_regncount + :count', array(':count' => 1))
->condition('vid', $selected_session_id)
->execute();
//store the selected variety sessions in an array of IDs
$booking_variety_ids[$id] = $selected_session_id;
}
//perform the insert to the booking_variety_regn table
db_insert('booking_variety_regn')
->fields(array(
'booking_variety_ids' => drupal_json_encode($booking_variety_ids),
'booking_person_nid' => $values['booking_nid'],
))
->execute();
drupal_set_message("Thanks for submitting your variety session registration.", $type = 'status');
$form_state['redirect'] = array('');
}

134
deprecated.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
// This code doesnt work since we can't use ajax_command_replace to replace form elements
// But its a handy reference point for failure
function booking_variety_session_callback($form, &$form_state) {
global $event;
$commands = array();
//$node = $form_state['values']['form_id'];
$data = $form_state['input'];
watchdog('booking_debug', 'booking_variety_session_callback:<br /><pre>@info</pre>', array('@info' => print_r( $form, true)));
// --- Update the wrapper for booking ID validity ---
//verify that user-entered data is a number
if (! preg_match('/^[0-9]+$/', $data['booking_nid'])) {
watchdog('booking_debug', "<pre>booking_variety_session_callback non-numerical input</pre>");
$markup = '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#8c2e0b;font-weight: bold;">' .
'You have not entered a valid booking reference number.</span></div>';
$commands[] = ajax_command_replace('#booking_variety_regn_feedback_wrapper', $markup);
}
// Perform lookup on barcode to make sure it matches someone attending the current event
$db_and = db_and();
$db_and->condition('p.booking_eventid', $event->eid, '=');
$db_and->condition('p.booking_status', 1, '=');
$db_and->condition('p.nid', $data['booking_nid'], '=');
$query = db_select('booking_person', 'p');
$query->condition($db_and)
->fields('p');
$person = $query->execute()
->fetchObject();
if ($person) {
watchdog('booking_debug', "<pre>booking_variety_session_callback found valid attendee</pre>");
$markup = '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#234600;font-weight: bold;">' .
'Matched booking reference number.</span></div>';
$commands[] = ajax_command_replace('#booking_variety_regn_feedback_wrapper', $markup);
}
else {
watchdog('booking_debug', "<pre>booking_variety_session_callback did not find valid attendee</pre>");
$markup = '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#8c2e0b;font-weight: bold;">' .
'You have not entered a valid booking reference number.</span></div>';
$commands[] = ajax_command_replace('#booking_variety_regn_feedback_wrapper', $markup);
}
// --- Update the wrapper for available variety sessions ---
// Query the variety timeslot table
$timeslot_query = db_select('booking_variety_timeslots', 'v');
$timeslot_query->condition('v.booking_eventid', $event->eid, '=')
->fields('v')
->orderBy('v.booking_variety_start');
$result = $timeslot_query->execute();
//for each entry in the variety timeslot table, create a new form select item
foreach($result as $timeslot) {
$fieldname = 'select-variety-' . $timeslot->tid;
$options = _booking_get_variety_timeslot_options($timeslot->tid);
watchdog('booking_debug', 'Timeslot @tid form state value: <pre>@info</pre>',
array('@tid' => $timeslot->tid, '@info' => print_r($form_state['values'], true)));
watchdog('booking_debug', 'Setting timeslot @tid default value to @value', array(
'@tid' => $timeslot->tid,
'@value' => isset($form_state['values'][$fieldname]) ? $form_state['values'][$fieldname] : 0)
);
//re-create the form element for this timeslot
$form['variety-sessions'][$fieldname] = array(
'#type' => 'select',
'#title' => t('Rebuilt Variety Session: ' . $timeslot->booking_variety_time_descrip),
'#required' => TRUE,
'#options' => $options,
'#prefix' => '<div id="booking_variety_session_' . $timeslot->tid . '_wrapper">',
'#suffix' => '</div>',
'#default_value' => 1,
);
//$form['variety-sessions'][$fieldname]['#options'] = $options;
//$form['variety-sessions'][$fieldname]['#title'] = t('Rebuilt Variety Session: ' . $timeslot->booking_variety_time_descrip);
// Tell drupal to update the wrapper for this field
$commands[] = ajax_command_replace('#booking_variety_session_' . $timeslot->tid . '_wrapper', drupal_render($form['form']['variety-sessions'][$fieldname]));
//$commands[] = ajax_command_replace('#booking_variety_session_' . $timeslot->tid . '_wrapper', drupal_render($form));
}
$form_state['rebuild'] = TRUE;
return array('#type' => 'ajax', '#commands' => $commands);
//$page = array('#type' => 'ajax', '#commands' => $commands);
//ajax_deliver($page);
}
/**
* Callback function to verify if barcode was valid
*/
function booking_variety_regn_callback($form, &$form_state) {
global $event;
//$node = $form_state['values']['form_id'];
$data = $form_state['input'];
watchdog('booking', '<pre>booking_variety_regn_callback validation:\n@info</pre>', array('@info' => print_r( $data, true)));
//verify that user-entered data is a number
if (! preg_match('/^[0-9]+$/', $data['booking_nid'])) {
watchdog('booking_debug', "<pre>booking_variety_regn_callback non-numerical input</pre>");
return '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#8c2e0b;font-weight: bold;">' .
'You have not entered a valid booking reference number.</span></div>';
}
// Perform lookup on barcode to make sure it matches someone attending the current event
$db_and = db_and();
$db_and->condition('p.booking_eventid', $event->eid, '=');
$db_and->condition('p.booking_status', 1, '=');
$db_and->condition('p.nid', $data['booking_nid'], '=');
$query = db_select('booking_person', 'p');
$query->condition($db_and)
->fields('p');
$person = $query->execute()
->fetchObject();
if ($person) {
watchdog('booking_debug', "<pre>booking_variety_regn_callback found valid attendee</pre>");
return '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#234600;font-weight: bold;">' .
'Matched booking reference number.</span></div>';
}
else {
watchdog('booking_debug', "<pre>booking_variety_regn_callback did not find valid attendee</pre>");
return '<div id="booking_variety_regn_feedback_wrapper" class="form-item"><span style="color:#8c2e0b;font-weight: bold;">' .
'You have not entered a valid booking reference number.</span></div>';
}
}

BIN
images/Final_Logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
images/facebook@2x.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
images/instagram@2x.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
images/twitter@2x.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
images/youtube@2x.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,968 @@
<?php
/*
* @license MIT License
* */
class XLSXWriter
{
//http://www.ecma-international.org/publications/standards/Ecma-376.htm
//http://officeopenxml.com/SSstyles.php
//------------------------------------------------------------------
//http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP010073849.aspx
const EXCEL_2007_MAX_ROW=1048576;
const EXCEL_2007_MAX_COL=16384;
//------------------------------------------------------------------
protected $title;
protected $subject;
protected $author;
protected $company;
protected $description;
protected $keywords = array();
protected $current_sheet;
protected $sheets = array();
protected $temp_files = array();
protected $cell_styles = array();
protected $number_formats = array();
public function __construct()
{
if(!ini_get('date.timezone'))
{
//using date functions can kick out warning if this isn't set
date_default_timezone_set('UTC');
}
$this->addCellStyle($number_format='GENERAL', $style_string=null);
$this->addCellStyle($number_format='GENERAL', $style_string=null);
$this->addCellStyle($number_format='GENERAL', $style_string=null);
$this->addCellStyle($number_format='GENERAL', $style_string=null);
}
public function setTitle($title='') { $this->title=$title; }
public function setSubject($subject='') { $this->subject=$subject; }
public function setAuthor($author='') { $this->author=$author; }
public function setCompany($company='') { $this->company=$company; }
public function setKeywords($keywords='') { $this->keywords=$keywords; }
public function setDescription($description='') { $this->description=$description; }
public function setTempDir($tempdir='') { $this->tempdir=$tempdir; }
public function __destruct()
{
if (!empty($this->temp_files)) {
foreach($this->temp_files as $temp_file) {
@unlink($temp_file);
}
}
}
protected function tempFilename()
{
$tempdir = !empty($this->tempdir) ? $this->tempdir : sys_get_temp_dir();
$filename = tempnam($tempdir, "xlsx_writer_");
$this->temp_files[] = $filename;
return $filename;
}
public function writeToStdOut()
{
$temp_file = $this->tempFilename();
self::writeToFile($temp_file);
readfile($temp_file);
}
public function writeToString()
{
$temp_file = $this->tempFilename();
self::writeToFile($temp_file);
$string = file_get_contents($temp_file);
return $string;
}
public function writeToFile($filename)
{
foreach($this->sheets as $sheet_name => $sheet) {
self::finalizeSheet($sheet_name);//making sure all footers have been written
}
if ( file_exists( $filename ) ) {
if ( is_writable( $filename ) ) {
@unlink( $filename ); //if the zip already exists, remove it
} else {
self::log( "Error in " . __CLASS__ . "::" . __FUNCTION__ . ", file is not writeable." );
return;
}
}
$zip = new ZipArchive();
if (empty($this->sheets)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", no worksheets defined."); return; }
if (!$zip->open($filename, ZipArchive::CREATE)) { self::log("Error in ".__CLASS__."::".__FUNCTION__.", unable to create zip."); return; }
$zip->addEmptyDir("docProps/");
$zip->addFromString("docProps/app.xml" , self::buildAppXML() );
$zip->addFromString("docProps/core.xml", self::buildCoreXML());
$zip->addEmptyDir("_rels/");
$zip->addFromString("_rels/.rels", self::buildRelationshipsXML());
$zip->addEmptyDir("xl/worksheets/");
foreach($this->sheets as $sheet) {
$zip->addFile($sheet->filename, "xl/worksheets/".$sheet->xmlname );
}
$zip->addFromString("xl/workbook.xml" , self::buildWorkbookXML() );
$zip->addFile($this->writeStylesXML(), "xl/styles.xml" ); //$zip->addFromString("xl/styles.xml" , self::buildStylesXML() );
$zip->addFromString("[Content_Types].xml" , self::buildContentTypesXML() );
$zip->addEmptyDir("xl/_rels/");
$zip->addFromString("xl/_rels/workbook.xml.rels", self::buildWorkbookRelsXML() );
$zip->close();
}
protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filter=false, $freeze_rows=false, $freeze_columns=false )
{
//if already initialized
if ($this->current_sheet==$sheet_name || isset($this->sheets[$sheet_name]))
return;
$sheet_filename = $this->tempFilename();
$sheet_xmlname = 'sheet' . (count($this->sheets) + 1).".xml";
$this->sheets[$sheet_name] = (object)array(
'filename' => $sheet_filename,
'sheetname' => $sheet_name,
'xmlname' => $sheet_xmlname,
'row_count' => 0,
'file_writer' => new XLSXWriter_BuffererWriter($sheet_filename),
'columns' => array(),
'merge_cells' => array(),
'max_cell_tag_start' => 0,
'max_cell_tag_end' => 0,
'auto_filter' => $auto_filter,
'freeze_rows' => $freeze_rows,
'freeze_columns' => $freeze_columns,
'finalized' => false,
);
$sheet = &$this->sheets[$sheet_name];
$tabselected = count($this->sheets) == 1 ? 'true' : 'false';//only first sheet is selected
$max_cell=XLSXWriter::xlsCell(self::EXCEL_2007_MAX_ROW, self::EXCEL_2007_MAX_COL);//XFE1048577
$sheet->file_writer->write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n");
$sheet->file_writer->write('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
$sheet->file_writer->write( '<sheetPr filterMode="false">');
$sheet->file_writer->write( '<pageSetUpPr fitToPage="false"/>');
$sheet->file_writer->write( '</sheetPr>');
$sheet->max_cell_tag_start = $sheet->file_writer->ftell();
$sheet->file_writer->write('<dimension ref="A1:' . $max_cell . '"/>');
$sheet->max_cell_tag_end = $sheet->file_writer->ftell();
$sheet->file_writer->write( '<sheetViews>');
$sheet->file_writer->write( '<sheetView colorId="64" defaultGridColor="true" rightToLeft="false" showFormulas="false" showGridLines="true" showOutlineSymbols="true" showRowColHeaders="true" showZeros="true" tabSelected="' . $tabselected . '" topLeftCell="A1" view="normal" windowProtection="false" workbookViewId="0" zoomScale="100" zoomScaleNormal="100" zoomScalePageLayoutView="100">');
if ($sheet->freeze_rows && $sheet->freeze_columns) {
$sheet->file_writer->write( '<pane ySplit="'.$sheet->freeze_rows.'" xSplit="'.$sheet->freeze_columns.'" topLeftCell="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'" activePane="bottomRight" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activeCellId="0" pane="topRight" sqref="'.self::xlsCell($sheet->freeze_rows, 0).'"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activeCellId="0" pane="bottomLeft" sqref="'.self::xlsCell(0, $sheet->freeze_columns).'"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'" activeCellId="0" pane="bottomRight" sqref="'.self::xlsCell($sheet->freeze_rows, $sheet->freeze_columns).'"/>');
}
elseif ($sheet->freeze_rows) {
$sheet->file_writer->write( '<pane ySplit="'.$sheet->freeze_rows.'" topLeftCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activePane="bottomLeft" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell($sheet->freeze_rows, 0).'" activeCellId="0" pane="bottomLeft" sqref="'.self::xlsCell($sheet->freeze_rows, 0).'"/>');
}
elseif ($sheet->freeze_columns) {
$sheet->file_writer->write( '<pane xSplit="'.$sheet->freeze_columns.'" topLeftCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activePane="topRight" state="frozen"/>');
$sheet->file_writer->write( '<selection activeCell="'.self::xlsCell(0, $sheet->freeze_columns).'" activeCellId="0" pane="topRight" sqref="'.self::xlsCell(0, $sheet->freeze_columns).'"/>');
}
else { // not frozen
$sheet->file_writer->write( '<selection activeCell="A1" activeCellId="0" pane="topLeft" sqref="A1"/>');
}
$sheet->file_writer->write( '</sheetView>');
$sheet->file_writer->write( '</sheetViews>');
$sheet->file_writer->write( '<cols>');
$i=0;
if (!empty($col_widths)) {
foreach($col_widths as $column_width) {
$sheet->file_writer->write( '<col collapsed="false" hidden="false" max="'.($i+1).'" min="'.($i+1).'" style="0" customWidth="true" width="'.floatval($column_width).'"/>');
$i++;
}
}
$sheet->file_writer->write( '<col collapsed="false" hidden="false" max="1024" min="'.($i+1).'" style="0" customWidth="false" width="11.5"/>');
$sheet->file_writer->write( '</cols>');
$sheet->file_writer->write( '<sheetData>');
}
private function addCellStyle($number_format, $cell_style_string)
{
$number_format_idx = self::add_to_list_get_index($this->number_formats, $number_format);
$lookup_string = $number_format_idx.";".$cell_style_string;
$cell_style_idx = self::add_to_list_get_index($this->cell_styles, $lookup_string);
return $cell_style_idx;
}
private function initializeColumnTypes($header_types)
{
$column_types = array();
foreach($header_types as $v)
{
$number_format = self::numberFormatStandardized($v);
$number_format_type = self::determineNumberFormatType($number_format);
$cell_style_idx = $this->addCellStyle($number_format, $style_string=null);
$column_types[] = array('number_format' => $number_format,//contains excel format like 'YYYY-MM-DD HH:MM:SS'
'number_format_type' => $number_format_type, //contains friendly format like 'datetime'
'default_cell_style' => $cell_style_idx,
);
}
return $column_types;
}
public function writeSheetHeader($sheet_name, array $header_types, $col_options = null)
{
if (empty($sheet_name) || empty($header_types) || !empty($this->sheets[$sheet_name]))
return;
$suppress_row = isset($col_options['suppress_row']) ? intval($col_options['suppress_row']) : false;
if (is_bool($col_options))
{
self::log( "Warning! passing $suppress_row=false|true to writeSheetHeader() is deprecated, this will be removed in a future version." );
$suppress_row = intval($col_options);
}
$style = &$col_options;
$col_widths = isset($col_options['widths']) ? (array)$col_options['widths'] : array();
$auto_filter = isset($col_options['auto_filter']) ? intval($col_options['auto_filter']) : false;
$freeze_rows = isset($col_options['freeze_rows']) ? intval($col_options['freeze_rows']) : false;
$freeze_columns = isset($col_options['freeze_columns']) ? intval($col_options['freeze_columns']) : false;
self::initializeSheet($sheet_name, $col_widths, $auto_filter, $freeze_rows, $freeze_columns);
$sheet = &$this->sheets[$sheet_name];
$sheet->columns = $this->initializeColumnTypes($header_types);
if (!$suppress_row)
{
$header_row = array_keys($header_types);
$sheet->file_writer->write('<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="' . (1) . '">');
foreach ($header_row as $c => $v) {
$cell_style_idx = empty($style) ? $sheet->columns[$c]['default_cell_style'] : $this->addCellStyle( 'GENERAL', json_encode(isset($style[0]) ? $style[$c] : $style) );
$this->writeCell($sheet->file_writer, 0, $c, $v, $number_format_type='n_string', $cell_style_idx);
}
$sheet->file_writer->write('</row>');
$sheet->row_count++;
}
$this->current_sheet = $sheet_name;
}
public function writeSheetRow($sheet_name, array $row, $row_options=null)
{
if (empty($sheet_name))
return;
self::initializeSheet($sheet_name);
$sheet = &$this->sheets[$sheet_name];
if (count($sheet->columns) < count($row)) {
$default_column_types = $this->initializeColumnTypes( array_fill($from=0, $until=count($row), 'GENERAL') );//will map to n_auto
$sheet->columns = array_merge((array)$sheet->columns, $default_column_types);
}
if (!empty($row_options))
{
$ht = isset($row_options['height']) ? floatval($row_options['height']) : 12.1;
$customHt = isset($row_options['height']) ? true : false;
$hidden = isset($row_options['hidden']) ? (bool)($row_options['hidden']) : false;
$collapsed = isset($row_options['collapsed']) ? (bool)($row_options['collapsed']) : false;
$sheet->file_writer->write('<row collapsed="'.($collapsed).'" customFormat="false" customHeight="'.($customHt).'" hidden="'.($hidden).'" ht="'.($ht).'" outlineLevel="0" r="' . ($sheet->row_count + 1) . '">');
}
else
{
$sheet->file_writer->write('<row collapsed="false" customFormat="false" customHeight="false" hidden="false" ht="12.1" outlineLevel="0" r="' . ($sheet->row_count + 1) . '">');
}
$style = &$row_options;
$c=0;
foreach ($row as $v) {
$number_format = $sheet->columns[$c]['number_format'];
$number_format_type = $sheet->columns[$c]['number_format_type'];
$cell_style_idx = empty($style) ? $sheet->columns[$c]['default_cell_style'] : $this->addCellStyle( $number_format, json_encode(isset($style[0]) ? $style[$c] : $style) );
$this->writeCell($sheet->file_writer, $sheet->row_count, $c, $v, $number_format_type, $cell_style_idx);
$c++;
}
$sheet->file_writer->write('</row>');
$sheet->row_count++;
$this->current_sheet = $sheet_name;
}
public function countSheetRows($sheet_name = '')
{
$sheet_name = $sheet_name ?: $this->current_sheet;
return array_key_exists($sheet_name, $this->sheets) ? $this->sheets[$sheet_name]->row_count : 0;
}
protected function finalizeSheet($sheet_name)
{
if (empty($sheet_name) || $this->sheets[$sheet_name]->finalized)
return;
$sheet = &$this->sheets[$sheet_name];
$sheet->file_writer->write( '</sheetData>');
if (!empty($sheet->merge_cells)) {
$sheet->file_writer->write( '<mergeCells>');
foreach ($sheet->merge_cells as $range) {
$sheet->file_writer->write( '<mergeCell ref="' . $range . '"/>');
}
$sheet->file_writer->write( '</mergeCells>');
}
$max_cell = self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1);
if ($sheet->auto_filter) {
$sheet->file_writer->write( '<autoFilter ref="A1:' . $max_cell . '"/>');
}
$sheet->file_writer->write( '<printOptions headings="false" gridLines="false" gridLinesSet="true" horizontalCentered="false" verticalCentered="false"/>');
$sheet->file_writer->write( '<pageMargins left="0.5" right="0.5" top="1.0" bottom="1.0" header="0.5" footer="0.5"/>');
$sheet->file_writer->write( '<pageSetup blackAndWhite="false" cellComments="none" copies="1" draft="false" firstPageNumber="1" fitToHeight="1" fitToWidth="1" horizontalDpi="300" orientation="portrait" pageOrder="downThenOver" paperSize="1" scale="100" useFirstPageNumber="true" usePrinterDefaults="false" verticalDpi="300"/>');
$sheet->file_writer->write( '<headerFooter differentFirst="false" differentOddEven="false">');
$sheet->file_writer->write( '<oddHeader>&amp;C&amp;&quot;Times New Roman,Regular&quot;&amp;12&amp;A</oddHeader>');
$sheet->file_writer->write( '<oddFooter>&amp;C&amp;&quot;Times New Roman,Regular&quot;&amp;12Page &amp;P</oddFooter>');
$sheet->file_writer->write( '</headerFooter>');
$sheet->file_writer->write('</worksheet>');
$max_cell_tag = '<dimension ref="A1:' . $max_cell . '"/>';
$padding_length = $sheet->max_cell_tag_end - $sheet->max_cell_tag_start - strlen($max_cell_tag);
$sheet->file_writer->fseek($sheet->max_cell_tag_start);
$sheet->file_writer->write($max_cell_tag.str_repeat(" ", $padding_length));
$sheet->file_writer->close();
$sheet->finalized=true;
}
public function markMergedCell($sheet_name, $start_cell_row, $start_cell_column, $end_cell_row, $end_cell_column)
{
if (empty($sheet_name) || $this->sheets[$sheet_name]->finalized)
return;
self::initializeSheet($sheet_name);
$sheet = &$this->sheets[$sheet_name];
$startCell = self::xlsCell($start_cell_row, $start_cell_column);
$endCell = self::xlsCell($end_cell_row, $end_cell_column);
$sheet->merge_cells[] = $startCell . ":" . $endCell;
}
public function writeSheet(array $data, $sheet_name='', array $header_types=array())
{
$sheet_name = empty($sheet_name) ? 'Sheet1' : $sheet_name;
$data = empty($data) ? array(array('')) : $data;
if (!empty($header_types))
{
$this->writeSheetHeader($sheet_name, $header_types);
}
foreach($data as $i=>$row)
{
$this->writeSheetRow($sheet_name, $row);
}
$this->finalizeSheet($sheet_name);
}
protected function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $column_number, $value, $num_format_type, $cell_style_idx)
{
$cell_name = self::xlsCell($row_number, $column_number);
if (!is_scalar($value) || $value==='') { //objects, array, empty
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'"/>');
} elseif (is_string($value) && $value{0}=='='){
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="s"><f>'.self::xmlspecialchars($value).'</f></c>');
} elseif ($num_format_type=='n_date') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.intval(self::convert_date_time($value)).'</v></c>');
} elseif ($num_format_type=='n_datetime') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::convert_date_time($value).'</v></c>');
} elseif ($num_format_type=='n_numeric') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::xmlspecialchars($value).'</v></c>');//int,float,currency
} elseif ($num_format_type=='n_string') {
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="inlineStr"><is><t>'.self::xmlspecialchars($value).'</t></is></c>');
} elseif ($num_format_type=='n_auto' || 1) { //auto-detect unknown column types
if (!is_string($value) || $value=='0' || ($value[0]!='0' && ctype_digit($value)) || preg_match("/^\-?(0|[1-9][0-9]*)(\.[0-9]+)?$/", $value)){
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="n"><v>'.self::xmlspecialchars($value).'</v></c>');//int,float,currency
} else { //implied: ($cell_format=='string')
$file->write('<c r="'.$cell_name.'" s="'.$cell_style_idx.'" t="inlineStr"><is><t>'.self::xmlspecialchars($value).'</t></is></c>');
}
}
}
protected function styleFontIndexes()
{
static $border_allowed = array('left','right','top','bottom');
static $border_style_allowed = array('thin','medium','thick','dashDot','dashDotDot','dashed','dotted','double','hair','mediumDashDot','mediumDashDotDot','mediumDashed','slantDashDot');
static $horizontal_allowed = array('general','left','right','justify','center');
static $vertical_allowed = array('bottom','center','distributed','top');
$default_font = array('size'=>'10','name'=>'Arial','family'=>'2');
$fills = array('','');//2 placeholders for static xml later
$fonts = array('','','','');//4 placeholders for static xml later
$borders = array('');//1 placeholder for static xml later
$style_indexes = array();
foreach($this->cell_styles as $i=>$cell_style_string)
{
$semi_colon_pos = strpos($cell_style_string,";");
$number_format_idx = substr($cell_style_string, 0, $semi_colon_pos);
$style_json_string = substr($cell_style_string, $semi_colon_pos+1);
$style = @json_decode($style_json_string, $as_assoc=true);
$style_indexes[$i] = array('num_fmt_idx'=>$number_format_idx);//initialize entry
if (isset($style['border']) && is_string($style['border']))//border is a comma delimited str
{
$border_value['side'] = array_intersect(explode(",", $style['border']), $border_allowed);
if (isset($style['border-style']) && in_array($style['border-style'],$border_style_allowed))
{
$border_value['style'] = $style['border-style'];
}
if (isset($style['border-color']) && is_string($style['border-color']) && $style['border-color'][0]=='#')
{
$v = substr($style['border-color'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$border_value['color'] = "FF".strtoupper($v);
}
$style_indexes[$i]['border_idx'] = self::add_to_list_get_index($borders, json_encode($border_value));
}
if (isset($style['fill']) && is_string($style['fill']) && $style['fill'][0]=='#')
{
$v = substr($style['fill'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$style_indexes[$i]['fill_idx'] = self::add_to_list_get_index($fills, "FF".strtoupper($v) );
}
if (isset($style['halign']) && in_array($style['halign'],$horizontal_allowed))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['halign'] = $style['halign'];
}
if (isset($style['valign']) && in_array($style['valign'],$vertical_allowed))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['valign'] = $style['valign'];
}
if (isset($style['wrap_text']))
{
$style_indexes[$i]['alignment'] = true;
$style_indexes[$i]['wrap_text'] = (bool)$style['wrap_text'];
}
$font = $default_font;
if (isset($style['font-size']))
{
$font['size'] = floatval($style['font-size']);//floatval to allow "10.5" etc
}
if (isset($style['font']) && is_string($style['font']))
{
if ($style['font']=='Comic Sans MS') { $font['family']=4; }
if ($style['font']=='Times New Roman') { $font['family']=1; }
if ($style['font']=='Courier New') { $font['family']=3; }
$font['name'] = strval($style['font']);
}
if (isset($style['font-style']) && is_string($style['font-style']))
{
if (strpos($style['font-style'], 'bold')!==false) { $font['bold'] = true; }
if (strpos($style['font-style'], 'italic')!==false) { $font['italic'] = true; }
if (strpos($style['font-style'], 'strike')!==false) { $font['strike'] = true; }
if (strpos($style['font-style'], 'underline')!==false) { $font['underline'] = true; }
}
if (isset($style['color']) && is_string($style['color']) && $style['color'][0]=='#' )
{
$v = substr($style['color'],1,6);
$v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00
$font['color'] = "FF".strtoupper($v);
}
if ($font!=$default_font)
{
$style_indexes[$i]['font_idx'] = self::add_to_list_get_index($fonts, json_encode($font) );
}
}
return array('fills'=>$fills,'fonts'=>$fonts,'borders'=>$borders,'styles'=>$style_indexes );
}
protected function writeStylesXML()
{
$r = self::styleFontIndexes();
$fills = $r['fills'];
$fonts = $r['fonts'];
$borders = $r['borders'];
$style_indexes = $r['styles'];
$temporary_filename = $this->tempFilename();
$file = new XLSXWriter_BuffererWriter($temporary_filename);
$file->write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n");
$file->write('<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">');
$file->write('<numFmts count="'.count($this->number_formats).'">');
foreach($this->number_formats as $i=>$v) {
$file->write('<numFmt numFmtId="'.(164+$i).'" formatCode="'.self::xmlspecialchars($v).'" />');
}
//$file->write( '<numFmt formatCode="GENERAL" numFmtId="164"/>');
//$file->write( '<numFmt formatCode="[$$-1009]#,##0.00;[RED]\-[$$-1009]#,##0.00" numFmtId="165"/>');
//$file->write( '<numFmt formatCode="YYYY-MM-DD\ HH:MM:SS" numFmtId="166"/>');
//$file->write( '<numFmt formatCode="YYYY-MM-DD" numFmtId="167"/>');
$file->write('</numFmts>');
$file->write('<fonts count="'.(count($fonts)).'">');
$file->write( '<font><name val="Arial"/><charset val="1"/><family val="2"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
$file->write( '<font><name val="Arial"/><family val="0"/><sz val="10"/></font>');
foreach($fonts as $font) {
if (!empty($font)) { //fonts have 4 empty placeholders in array to offset the 4 static xml entries above
$f = json_decode($font,true);
$file->write('<font>');
$file->write( '<name val="'.htmlspecialchars($f['name']).'"/><charset val="1"/><family val="'.intval($f['family']).'"/>');
$file->write( '<sz val="'.intval($f['size']).'"/>');
if (!empty($f['color'])) { $file->write('<color rgb="'.strval($f['color']).'"/>'); }
if (!empty($f['bold'])) { $file->write('<b val="true"/>'); }
if (!empty($f['italic'])) { $file->write('<i val="true"/>'); }
if (!empty($f['underline'])) { $file->write('<u val="single"/>'); }
if (!empty($f['strike'])) { $file->write('<strike val="true"/>'); }
$file->write('</font>');
}
}
$file->write('</fonts>');
$file->write('<fills count="'.(count($fills)).'">');
$file->write( '<fill><patternFill patternType="none"/></fill>');
$file->write( '<fill><patternFill patternType="gray125"/></fill>');
foreach($fills as $fill) {
if (!empty($fill)) { //fills have 2 empty placeholders in array to offset the 2 static xml entries above
$file->write('<fill><patternFill patternType="solid"><fgColor rgb="'.strval($fill).'"/><bgColor indexed="64"/></patternFill></fill>');
}
}
$file->write('</fills>');
$file->write('<borders count="'.(count($borders)).'">');
$file->write( '<border diagonalDown="false" diagonalUp="false"><left/><right/><top/><bottom/><diagonal/></border>');
foreach($borders as $border) {
if (!empty($border)) { //fonts have an empty placeholder in the array to offset the static xml entry above
$pieces = json_decode($border,true);
$border_style = !empty($pieces['style']) ? $pieces['style'] : 'hair';
$border_color = !empty($pieces['color']) ? '<color rgb="'.strval($pieces['color']).'"/>' : '';
$file->write('<border diagonalDown="false" diagonalUp="false">');
foreach (array('left', 'right', 'top', 'bottom') as $side)
{
$show_side = in_array($side,$pieces['side']) ? true : false;
$file->write($show_side ? "<$side style=\"$border_style\">$border_color</$side>" : "<$side/>");
}
$file->write( '<diagonal/>');
$file->write('</border>');
}
}
$file->write('</borders>');
$file->write('<cellStyleXfs count="20">');
$file->write( '<xf applyAlignment="true" applyBorder="true" applyFont="true" applyProtection="true" borderId="0" fillId="0" fontId="0" numFmtId="164">');
$file->write( '<alignment horizontal="general" indent="0" shrinkToFit="false" textRotation="0" vertical="bottom" wrapText="false"/>');
$file->write( '<protection hidden="false" locked="true"/>');
$file->write( '</xf>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="2" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="0"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="43"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="41"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="44"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="42"/>');
$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="true" applyProtection="false" borderId="0" fillId="0" fontId="1" numFmtId="9"/>');
$file->write('</cellStyleXfs>');
$file->write('<cellXfs count="'.(count($style_indexes)).'">');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="164" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="165" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="166" xfId="0"/>');
//$file->write( '<xf applyAlignment="false" applyBorder="false" applyFont="false" applyProtection="false" borderId="0" fillId="0" fontId="0" numFmtId="167" xfId="0"/>');
foreach($style_indexes as $v)
{
$applyAlignment = isset($v['alignment']) ? 'true' : 'false';
$wrapText = !empty($v['wrap_text']) ? 'true' : 'false';
$horizAlignment = isset($v['halign']) ? $v['halign'] : 'general';
$vertAlignment = isset($v['valign']) ? $v['valign'] : 'bottom';
$applyBorder = isset($v['border_idx']) ? 'true' : 'false';
$applyFont = 'true';
$borderIdx = isset($v['border_idx']) ? intval($v['border_idx']) : 0;
$fillIdx = isset($v['fill_idx']) ? intval($v['fill_idx']) : 0;
$fontIdx = isset($v['font_idx']) ? intval($v['font_idx']) : 0;
//$file->write('<xf applyAlignment="'.$applyAlignment.'" applyBorder="'.$applyBorder.'" applyFont="'.$applyFont.'" applyProtection="false" borderId="'.($borderIdx).'" fillId="'.($fillIdx).'" fontId="'.($fontIdx).'" numFmtId="'.(164+$v['num_fmt_idx']).'" xfId="0"/>');
$file->write('<xf applyAlignment="'.$applyAlignment.'" applyBorder="'.$applyBorder.'" applyFont="'.$applyFont.'" applyProtection="false" borderId="'.($borderIdx).'" fillId="'.($fillIdx).'" fontId="'.($fontIdx).'" numFmtId="'.(164+$v['num_fmt_idx']).'" xfId="0">');
$file->write(' <alignment horizontal="'.$horizAlignment.'" vertical="'.$vertAlignment.'" textRotation="0" wrapText="'.$wrapText.'" indent="0" shrinkToFit="false"/>');
$file->write(' <protection locked="true" hidden="false"/>');
$file->write('</xf>');
}
$file->write('</cellXfs>');
$file->write( '<cellStyles count="6">');
$file->write( '<cellStyle builtinId="0" customBuiltin="false" name="Normal" xfId="0"/>');
$file->write( '<cellStyle builtinId="3" customBuiltin="false" name="Comma" xfId="15"/>');
$file->write( '<cellStyle builtinId="6" customBuiltin="false" name="Comma [0]" xfId="16"/>');
$file->write( '<cellStyle builtinId="4" customBuiltin="false" name="Currency" xfId="17"/>');
$file->write( '<cellStyle builtinId="7" customBuiltin="false" name="Currency [0]" xfId="18"/>');
$file->write( '<cellStyle builtinId="5" customBuiltin="false" name="Percent" xfId="19"/>');
$file->write( '</cellStyles>');
$file->write('</styleSheet>');
$file->close();
return $temporary_filename;
}
protected function buildAppXML()
{
$app_xml="";
$app_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$app_xml.='<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">';
$app_xml.='<TotalTime>0</TotalTime>';
$app_xml.='<Company>'.self::xmlspecialchars($this->company).'</Company>';
$app_xml.='</Properties>';
return $app_xml;
}
protected function buildCoreXML()
{
$core_xml="";
$core_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$core_xml.='<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
$core_xml.='<dcterms:created xsi:type="dcterms:W3CDTF">'.date("Y-m-d\TH:i:s.00\Z").'</dcterms:created>';//$date_time = '2014-10-25T15:54:37.00Z';
$core_xml.='<dc:title>'.self::xmlspecialchars($this->title).'</dc:title>';
$core_xml.='<dc:subject>'.self::xmlspecialchars($this->subject).'</dc:subject>';
$core_xml.='<dc:creator>'.self::xmlspecialchars($this->author).'</dc:creator>';
if (!empty($this->keywords)) {
$core_xml.='<cp:keywords>'.self::xmlspecialchars(implode (", ", (array)$this->keywords)).'</cp:keywords>';
}
$core_xml.='<dc:description>'.self::xmlspecialchars($this->description).'</dc:description>';
$core_xml.='<cp:revision>0</cp:revision>';
$core_xml.='</cp:coreProperties>';
return $core_xml;
}
protected function buildRelationshipsXML()
{
$rels_xml="";
$rels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$rels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
$rels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>';
$rels_xml.='<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>';
$rels_xml.='<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>';
$rels_xml.="\n";
$rels_xml.='</Relationships>';
return $rels_xml;
}
protected function buildWorkbookXML()
{
$i=0;
$workbook_xml="";
$workbook_xml.='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n";
$workbook_xml.='<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">';
$workbook_xml.='<fileVersion appName="Calc"/><workbookPr backupFile="false" showObjects="all" date1904="false"/><workbookProtection/>';
$workbook_xml.='<bookViews><workbookView activeTab="0" firstSheet="0" showHorizontalScroll="true" showSheetTabs="true" showVerticalScroll="true" tabRatio="212" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"/></bookViews>';
$workbook_xml.='<sheets>';
foreach($this->sheets as $sheet_name=>$sheet) {
$sheetname = self::sanitize_sheetname($sheet->sheetname);
$workbook_xml.='<sheet name="'.self::xmlspecialchars($sheetname).'" sheetId="'.($i+1).'" state="visible" r:id="rId'.($i+2).'"/>';
$i++;
}
$workbook_xml.='</sheets>';
$workbook_xml.='<definedNames>';
foreach($this->sheets as $sheet_name=>$sheet) {
if ($sheet->auto_filter) {
$sheetname = self::sanitize_sheetname($sheet->sheetname);
$workbook_xml.='<definedName name="_xlnm._FilterDatabase" localSheetId="0" hidden="1">\''.self::xmlspecialchars($sheetname).'\'!$A$1:' . self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1, true) . '</definedName>';
$i++;
}
}
$workbook_xml.='</definedNames>';
$workbook_xml.='<calcPr iterateCount="100" refMode="A1" iterate="false" iterateDelta="0.001"/></workbook>';
return $workbook_xml;
}
protected function buildWorkbookRelsXML()
{
$i=0;
$wkbkrels_xml="";
$wkbkrels_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$wkbkrels_xml.='<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">';
$wkbkrels_xml.='<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>';
foreach($this->sheets as $sheet_name=>$sheet) {
$wkbkrels_xml.='<Relationship Id="rId'.($i+2).'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/'.($sheet->xmlname).'"/>';
$i++;
}
$wkbkrels_xml.="\n";
$wkbkrels_xml.='</Relationships>';
return $wkbkrels_xml;
}
protected function buildContentTypesXML()
{
$content_types_xml="";
$content_types_xml.='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$content_types_xml.='<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">';
$content_types_xml.='<Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
$content_types_xml.='<Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>';
foreach($this->sheets as $sheet_name=>$sheet) {
$content_types_xml.='<Override PartName="/xl/worksheets/'.($sheet->xmlname).'" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>';
}
$content_types_xml.='<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>';
$content_types_xml.='<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>';
$content_types_xml.='<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>';
$content_types_xml.='<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>';
$content_types_xml.="\n";
$content_types_xml.='</Types>';
return $content_types_xml;
}
//------------------------------------------------------------------
/*
* @param $row_number int, zero based
* @param $column_number int, zero based
* @param $absolute bool
* @return Cell label/coordinates, ex: A1, C3, AA42 (or if $absolute==true: $A$1, $C$3, $AA$42)
* */
public static function xlsCell($row_number, $column_number, $absolute=false)
{
$n = $column_number;
for($r = ""; $n >= 0; $n = intval($n / 26) - 1) {
$r = chr($n%26 + 0x41) . $r;
}
if ($absolute) {
return '$' . $r . '$' . ($row_number+1);
}
return $r . ($row_number+1);
}
//------------------------------------------------------------------
public static function log($string)
{
file_put_contents("php://stderr", date("Y-m-d H:i:s:").rtrim(is_array($string) ? json_encode($string) : $string)."\n");
}
//------------------------------------------------------------------
public static function sanitize_filename($filename) //http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
{
$nonprinting = array_map('chr', range(0,31));
$invalid_chars = array('<', '>', '?', '"', ':', '|', '\\', '/', '*', '&');
$all_invalids = array_merge($nonprinting,$invalid_chars);
return str_replace($all_invalids, "", $filename);
}
//------------------------------------------------------------------
public static function sanitize_sheetname($sheetname)
{
static $badchars = '\\/?*:[]';
static $goodchars = ' ';
$sheetname = strtr($sheetname, $badchars, $goodchars);
$sheetname = substr($sheetname, 0, 31);
$sheetname = trim(trim(trim($sheetname),"'"));//trim before and after trimming single quotes
return !empty($sheetname) ? $sheetname : 'Sheet'.((rand()%900)+100);
}
//------------------------------------------------------------------
public static function xmlspecialchars($val)
{
//note, badchars does not include \t\n\r (\x09\x0a\x0d)
static $badchars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f";
static $goodchars = " ";
return strtr(htmlspecialchars($val, ENT_QUOTES | ENT_XML1), $badchars, $goodchars);//strtr appears to be faster than str_replace
}
//------------------------------------------------------------------
public static function array_first_key(array $arr)
{
reset($arr);
$first_key = key($arr);
return $first_key;
}
//------------------------------------------------------------------
private static function determineNumberFormatType($num_format)
{
$num_format = preg_replace("/\[(Black|Blue|Cyan|Green|Magenta|Red|White|Yellow)\]/i", "", $num_format);
if ($num_format=='GENERAL') return 'n_auto';
if ($num_format=='@') return 'n_string';
if ($num_format=='0') return 'n_numeric';
if (preg_match("/[H]{1,2}:[M]{1,2}/i", $num_format)) return 'n_datetime';
if (preg_match("/[M]{1,2}:[S]{1,2}/i", $num_format)) return 'n_datetime';
if (preg_match("/[Y]{2,4}/i", $num_format)) return 'n_date';
if (preg_match("/[D]{1,2}/i", $num_format)) return 'n_date';
if (preg_match("/[M]{1,2}/i", $num_format)) return 'n_date';
if (preg_match("/$/", $num_format)) return 'n_numeric';
if (preg_match("/%/", $num_format)) return 'n_numeric';
if (preg_match("/0/", $num_format)) return 'n_numeric';
return 'n_auto';
}
//------------------------------------------------------------------
private static function numberFormatStandardized($num_format)
{
if ($num_format=='money') { $num_format='dollar'; }
if ($num_format=='number') { $num_format='integer'; }
if ($num_format=='string') $num_format='@';
else if ($num_format=='integer') $num_format='0';
else if ($num_format=='date') $num_format='YYYY-MM-DD';
else if ($num_format=='datetime') $num_format='YYYY-MM-DD HH:MM:SS';
else if ($num_format=='price') $num_format='#,##0.00';
else if ($num_format=='dollar') $num_format='[$$-1009]#,##0.00;[RED]-[$$-1009]#,##0.00';
else if ($num_format=='euro') $num_format='#,##0.00 [$€-407];[RED]-#,##0.00 [$€-407]';
$ignore_until='';
$escaped = '';
for($i=0,$ix=strlen($num_format); $i<$ix; $i++)
{
$c = $num_format[$i];
if ($ignore_until=='' && $c=='[')
$ignore_until=']';
else if ($ignore_until=='' && $c=='"')
$ignore_until='"';
else if ($ignore_until==$c)
$ignore_until='';
if ($ignore_until=='' && ($c==' ' || $c=='-' || $c=='(' || $c==')') && ($i==0 || $num_format[$i-1]!='_'))
$escaped.= "\\".$c;
else
$escaped.= $c;
}
return $escaped;
}
//------------------------------------------------------------------
public static function add_to_list_get_index(&$haystack, $needle)
{
$existing_idx = array_search($needle, $haystack, $strict=true);
if ($existing_idx===false)
{
$existing_idx = count($haystack);
$haystack[] = $needle;
}
return $existing_idx;
}
//------------------------------------------------------------------
public static function convert_date_time($date_input) //thanks to Excel::Writer::XLSX::Worksheet.pm (perl)
{
$days = 0; # Number of days since epoch
$seconds = 0; # Time expressed as fraction of 24h hours in seconds
$year=$month=$day=0;
$hour=$min =$sec=0;
$date_time = $date_input;
if (preg_match("/(\d{4})\-(\d{2})\-(\d{2})/", $date_time, $matches))
{
list($junk,$year,$month,$day) = $matches;
}
if (preg_match("/(\d+):(\d{2}):(\d{2})/", $date_time, $matches))
{
list($junk,$hour,$min,$sec) = $matches;
$seconds = ( $hour * 60 * 60 + $min * 60 + $sec ) / ( 24 * 60 * 60 );
}
//using 1900 as epoch, not 1904, ignoring 1904 special case
# Special cases for Excel.
if ("$year-$month-$day"=='1899-12-31') return $seconds ; # Excel 1900 epoch
if ("$year-$month-$day"=='1900-01-00') return $seconds ; # Excel 1900 epoch
if ("$year-$month-$day"=='1900-02-29') return 60 + $seconds ; # Excel false leapday
# We calculate the date by calculating the number of days since the epoch
# and adjust for the number of leap days. We calculate the number of leap
# days by normalising the year in relation to the epoch. Thus the year 2000
# becomes 100 for 4 and 100 year leapdays and 400 for 400 year leapdays.
$epoch = 1900;
$offset = 0;
$norm = 300;
$range = $year - $epoch;
# Set month days and check for leap year.
$leap = (($year % 400 == 0) || (($year % 4 == 0) && ($year % 100)) ) ? 1 : 0;
$mdays = array( 31, ($leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
# Some boundary checks
if($year < $epoch || $year > 9999) return 0;
if($month < 1 || $month > 12) return 0;
if($day < 1 || $day > $mdays[ $month - 1 ]) return 0;
# Accumulate the number of days since the epoch.
$days = $day; # Add days for current month
$days += array_sum( array_slice($mdays, 0, $month-1 ) ); # Add days for past months
$days += $range * 365; # Add days for past years
$days += intval( ( $range ) / 4 ); # Add leapdays
$days -= intval( ( $range + $offset ) / 100 ); # Subtract 100 year leapdays
$days += intval( ( $range + $offset + $norm ) / 400 ); # Add 400 year leapdays
$days -= $leap; # Already counted above
# Adjust for Excel erroneously treating 1900 as a leap year.
if ($days > 59) { $days++;}
return $days + $seconds;
}
//------------------------------------------------------------------
}
class XLSXWriter_BuffererWriter
{
protected $fd=null;
protected $buffer='';
protected $check_utf8=false;
public function __construct($filename, $fd_fopen_flags='w', $check_utf8=false)
{
$this->check_utf8 = $check_utf8;
$this->fd = fopen($filename, $fd_fopen_flags);
if ($this->fd===false) {
XLSXWriter::log("Unable to open $filename for writing.");
}
}
public function write($string)
{
$this->buffer.=$string;
if (isset($this->buffer[8191])) {
$this->purge();
}
}
protected function purge()
{
if ($this->fd) {
if ($this->check_utf8 && !self::isValidUTF8($this->buffer)) {
XLSXWriter::log("Error, invalid UTF8 encoding detected.");
$this->check_utf8 = false;
}
fwrite($this->fd, $this->buffer);
$this->buffer='';
}
}
public function close()
{
$this->purge();
if ($this->fd) {
fclose($this->fd);
$this->fd=null;
}
}
public function __destruct()
{
$this->close();
}
public function ftell()
{
if ($this->fd) {
$this->purge();
return ftell($this->fd);
}
return -1;
}
public function fseek($pos)
{
if ($this->fd) {
$this->purge();
return fseek($this->fd, $pos);
}
return -1;
}
protected static function isValidUTF8($string)
{
if (function_exists('mb_check_encoding'))
{
return mb_check_encoding($string, 'UTF-8') ? true : false;
}
return preg_match("//u", $string) ? true : false;
}
}
// vim: set filetype=php expandtab tabstop=4 shiftwidth=4 autoindent smartindent:

View File

@@ -0,0 +1,335 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head>
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width">
<!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->
<title></title>
<!--Study Week 2018 Template-->
<style type="text/css" id="media-query">
body {
margin: 0;
padding: 0; }
table, tr, td {
vertical-align: top;
border-collapse: collapse; }
.ie-browser table, .mso-container table {
table-layout: fixed; }
* {
line-height: inherit; }
a[x-apple-data-detectors=true] {
color: inherit !important;
text-decoration: none !important; }
[owa] .img-container div, [owa] .img-container button {
display: block !important; }
[owa] .fullwidth button {
width: 100% !important; }
[owa] .block-grid .col {
display: table-cell;
float: none !important;
vertical-align: top; }
.ie-browser .num12, .ie-browser .block-grid, [owa] .num12, [owa] .block-grid {
width: 700px !important; }
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {
line-height: 100%; }
.ie-browser .mixed-two-up .num4, [owa] .mixed-two-up .num4 {
width: 232px !important; }
.ie-browser .mixed-two-up .num8, [owa] .mixed-two-up .num8 {
width: 464px !important; }
.ie-browser .block-grid.two-up .col, [owa] .block-grid.two-up .col {
width: 350px !important; }
.ie-browser .block-grid.three-up .col, [owa] .block-grid.three-up .col {
width: 233px !important; }
.ie-browser .block-grid.four-up .col, [owa] .block-grid.four-up .col {
width: 175px !important; }
.ie-browser .block-grid.five-up .col, [owa] .block-grid.five-up .col {
width: 140px !important; }
.ie-browser .block-grid.six-up .col, [owa] .block-grid.six-up .col {
width: 116px !important; }
.ie-browser .block-grid.seven-up .col, [owa] .block-grid.seven-up .col {
width: 100px !important; }
.ie-browser .block-grid.eight-up .col, [owa] .block-grid.eight-up .col {
width: 87px !important; }
.ie-browser .block-grid.nine-up .col, [owa] .block-grid.nine-up .col {
width: 77px !important; }
.ie-browser .block-grid.ten-up .col, [owa] .block-grid.ten-up .col {
width: 70px !important; }
.ie-browser .block-grid.eleven-up .col, [owa] .block-grid.eleven-up .col {
width: 63px !important; }
.ie-browser .block-grid.twelve-up .col, [owa] .block-grid.twelve-up .col {
width: 58px !important; }
@media only screen and (min-width: 720px) {
.block-grid {
width: 700px !important; }
.block-grid .col {
vertical-align: top; }
.block-grid .col.num12 {
width: 700px !important; }
.block-grid.mixed-two-up .col.num4 {
width: 232px !important; }
.block-grid.mixed-two-up .col.num8 {
width: 464px !important; }
.block-grid.two-up .col {
width: 350px !important; }
.block-grid.three-up .col {
width: 233px !important; }
.block-grid.four-up .col {
width: 175px !important; }
.block-grid.five-up .col {
width: 140px !important; }
.block-grid.six-up .col {
width: 116px !important; }
.block-grid.seven-up .col {
width: 100px !important; }
.block-grid.eight-up .col {
width: 87px !important; }
.block-grid.nine-up .col {
width: 77px !important; }
.block-grid.ten-up .col {
width: 70px !important; }
.block-grid.eleven-up .col {
width: 63px !important; }
.block-grid.twelve-up .col {
width: 58px !important; } }
@media (max-width: 720px) {
.block-grid, .col {
min-width: 320px !important;
max-width: 100% !important;
display: block !important; }
.block-grid {
width: calc(100% - 40px) !important; }
.col {
width: 100% !important; }
.col > div {
margin: 0 auto; }
img.fullwidth {
max-width: 100% !important; } }
</style>
</head>
<body class="clean-body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: <?php print $colors['booking_mailtemplate_background_color'] ?>">
<style type="text/css" id="media-query-bodytag">
@media (max-width: 520px) {
.block-grid {
min-width: 320px!important;
max-width: 100%!important;
width: 100%!important;
display: block!important;
}
.col {
min-width: 320px!important;
max-width: 100%!important;
width: 100%!important;
display: block!important;
}
.col > div {
margin: 0 auto;
}
img.fullwidth {
max-width: 100%!important;
}
}
</style>
<!--[if IE]><div class="ie-browser"><![endif]-->
<!--[if mso]><div class="mso-container"><![endif]-->
<div class="nl-container" style="min-width: 320px;Margin: 0 auto;background-color: <?php print $colors['booking_mailtemplate_background_color'] ?>">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color: <?php print $colors['booking_mailtemplate_background_color'] ?>;"><![endif]-->
<div style="background-color:transparent;">
<div style="Margin: 0 auto;min-width: 320px;max-width: 700px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: <?php print $colors['booking_mailtemplate_background_color'] ?>;" class="block-grid ">
<div style="border-collapse: collapse;display: table;width: 100%;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background-color:transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width: 700px;"><tr class="layout-full-width" style="background-color:<?php print $colors['booking_mailtemplate_background_color'] ?>;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="700" style=" width:700px; padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><![endif]-->
<div class="col num12" style="min-width: 320px;max-width: 700px;display: table-cell;vertical-align: top;background-color: <?php print $colors['booking_mailtemplate_background_color'] ?>;">
<div style="background-color: transparent; width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;"><!--<![endif]-->
<div style="padding-right: 5px; padding-left: 5px; padding-top: 0px; padding-bottom: 0px;">
<!--[if (mso)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 5px;padding-left: 5px; padding-top: 0px; padding-bottom: 0px;"><table width="100%" align="center" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->
<div align="center">
<div style="border-top: 0px solid transparent; width:100%; line-height:0px; height:0px; font-size:0px;">&#160;</div>
</div>
<!--[if (mso)]></td></tr></table></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!--></div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!-- Header image -->
<div style="background-color:transparent;">
<div style="Margin: 0 auto;min-width: 320px;max-width: 700px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: <?php print $colors['booking_mailtemplate_header_background_color'] ?>;" class="block-grid ">
<div style="border-collapse: collapse;display: table;width: 100%;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background-color:transparent;" align="center"><table cellpadding="0" cellspacing="0" border="0" style="width: 700px;"><tr class="layout-full-width" style="background-color:<?php print $colors['booking_mailtemplate_header_background_color'] ?>;"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="700" style=" width:700px; padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><![endif]-->
<div class="col num12" style="min-width: 320px;max-width: 700px;display: table-cell;vertical-align: top;background-color: <?php print $colors['booking_mailtemplate_header_background_color'] ?>;">
<div style="background-color: transparent; width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;"><!--<![endif]-->
<div align="center" class="img-container center fullwidth" style="padding-right: 0px; padding-left: 0px;">
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px;" align="center"><![endif]-->
<div style="line-height:15px;font-size:1px">&#160;</div>
<a href="<?php print $colors['booking_mailtemplate_header_link_url'] ?>" target="_blank">
<img class="center fullwidth" align="center" border="0" src="<?php print $colors['booking_mailtemplate_header_image_url'] ?>" alt="Image" title="Image" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: 0;height: auto;float: none;width: 100%;max-width: 700px" width="700">
</a>
<div style="line-height:15px;font-size:1px">&#160;</div><!--[if mso]></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!--></div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!-- Menu bar -->
<div style="background-color:transparent;">
<div style="Margin: 0 auto;min-width: 320px;max-width: 700px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: <?php print $colors['booking_mailtemplate_navigation_background_color'] ?>;" class="block-grid three-up">
<div style="border-collapse: collapse;display: table;width: 100%;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background-color:transparent;" align="center">
<table cellpadding="0" cellspacing="0" border="0" style="width: 700px;">
<tr class="layout-full-width" style="background-color:<?php print $colors['booking_mailtemplate_navigation_background_color'] ?>;">
<![endif]-->
<?php foreach ($header_links as $linkitem) : ?>
<!--[if (mso)|(IE)]><td align="center" width="233" style=" width:233px; padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><![endif]-->
<div class="col num4" style="max-width: 320px;min-width: 233px;display: table-cell;vertical-align: top;background-color: <?php print $colors['booking_mailtemplate_navigation_background_color'] ?>;">
<div style="background-color: transparent; width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;"><!--<![endif]-->
<div align="center" class="button-container center" style="padding-right: 0px; padding-left: 0px; padding-top:0px; padding-bottom:0px;">
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing: 0; border-collapse: collapse; mso-table-lspace:0pt; mso-table-rspace:0pt;">
<tr>
<td style="padding-right: 0px; padding-left: 0px; padding-top:0px; padding-bottom:0px;" align="center">
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="<?php print $linkitem['link'] ?>" style="height:46px; v-text-anchor:middle; width:185px;" arcsize="9%" strokecolor="transparent" fillcolor="transparent"><w:anchorlock/>
<center style="color:<?php print $colors['booking_mailtemplate_header_text_color'] ?>; font-family:Verdana, Geneva, sans-serif; font-size:18px;">
<![endif]-->
<a href="<?php print $linkitem['link'] ?>" target="_blank" style="display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: <?php print $colors['booking_mailtemplate_header_text_color'] ?>;background-color: transparent;border-radius: 4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;max-width: 165px;width: auto;border-top: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-left: 0px solid transparent;padding-top: 5px;padding-right: 20px;padding-bottom: 5px;padding-left: 20px;font-family: Verdana, Geneva, sans-serif;mso-border-alt: none">
<span style="font-size: 18px; line-height: 36px;" data-mce-style="font-size: 18px; line-height: 36px;"><strong><?php print $linkitem['text'] ?></strong></span>
</a>
<!--[if mso]></center></v:roundrect></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!--></div><!--<![endif]-->
</div>
</div>
<?php endforeach; ?>
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<!-- Content section -->
<div style="background-color:transparent;">
<div style="Margin: 0 auto;min-width: 320px;max-width: 700px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: <?php print $colors['booking_mailtemplate_content_background_color'] ?>;" class="block-grid ">
<div style="border-collapse: collapse;display: table;width: 100%;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="background-color:transparent;" align="center">
<table cellpadding="0" cellspacing="0" border="0" style="width: 700px;">
<tr class="layout-full-width" style="background-color:<?php print $colors['booking_mailtemplate_content_background_color'] ?>;">
<td align="center" width="700" style=" width:700px; padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top">
<![endif]-->
<div class="col num12" style="min-width: 320px;max-width: 700px;display: table-cell;vertical-align: top;background-color: <?php print $colors['booking_mailtemplate_content_background_color'] ?>;">
<div style="background-color: transparent; width: 100% !important;">
<!--[if (!mso)&(!IE)]><!--><div style="border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;"><!--<![endif]-->
<!-- Subject -->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 20px; padding-bottom: 10px;"><![endif]-->
<div style="font-size:28px;line-height:43px;font-family:Verdana, Geneva, sans-serif;color:<?php print $colors['booking_mailtemplate_subjectheading_text_color'] ?>;text-align:left;">
<p style="margin: 0;text-align: center"><strong><?php print $subject ?></strong></p>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!-- Main body content -->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px;"><![endif]-->
<div style="font-family:'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;line-height:150%;color:<?php print $colors['booking_mailtemplate_text_color'] ?>; padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px;">
<?php print $body ?>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!-- Dotted dividing line -->
<div style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px;">
<!--[if (mso)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px;padding-left: 10px; padding-top: 10px; padding-bottom: 10px;"><table width="90%" align="center" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->
<div align="center">
<div style="border-top: 2px dotted #DAD8D8; width:90%; line-height:2px; height:2px; font-size:2px;">&#160;</div>
</div>
<!--[if (mso)]></td></tr></table></td></tr></table><![endif]-->
</div>
<!-- Footer section -->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 25px;"><![endif]-->
<div style="font-family:'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;color:#C4C4C4; padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 25px;">
<div style="font-size:12px;line-height:14px;text-align:left;"><?php print $footer ?></div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!-- Social Media section -->
<div align="center" style="padding-right: 10px; padding-left: 10px; padding-bottom: 10px;">
<div style="line-height:10px;font-size:1px">&#160;</div>
<div style="display: table; max-width:171px;">
<!--[if (mso)|(IE)]>
<table width="151" cellpadding="0" cellspacing="0" border="0"><tr><td style="border-collapse:collapse; padding-right: 10px; padding-left: 10px; padding-bottom: 10px;" align="center">
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace: 0pt;mso-table-rspace: 0pt; width:151px;">
<tr>
<![endif]-->
<?php foreach ($social_links as $linkitem) : ?>
<?php if (isset($linkitem['text']) && (! empty($linkitem['text']))) : ?>
<!--[if (mso)|(IE)]><td width="32" style="width:32px; padding-right: 15px;" valign="top"><![endif]-->
<table align="left" border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;Margin-right: 15px">
<tbody><tr style="vertical-align: top"><td align="left" valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href="<?php print $linkitem['linkurl'] ?>" title="<?php print $linkitem['text'] ?>" target="_blank">
<img src="<?php print $linkitem['imageurl'] ?>" alt="<?php print $linkitem['text'] ?>" title="<?php print $linkitem['text'] ?>" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important">
</a>
<div style="line-height:5px;font-size:1px">&#160;</div>
</td></tr>
</tbody></table>
<!--[if (mso)|(IE)]></td><![endif]-->
<?php endif; ?>
<?php endforeach; ?>
<!--[if (mso)|(IE)]></tr></table></td></tr></table><![endif]-->
</div>
</div>
<div style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px;">
<!--[if (mso)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px;padding-left: 10px; padding-top: 10px; padding-bottom: 10px;"><table width="100%" align="center" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->
<div align="center">
<div style="border-top: 1px solid #BBBBBB; width:100%; line-height:1px; height:1px; font-size:1px;">&#160;</div>
</div>
<!--[if (mso)]></td></tr></table></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!--></div><!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div> <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
</div>
<!--[if (mso)|(IE)]></div><![endif]-->
</body></html>

View File

@@ -0,0 +1,40 @@
<?php
/**
* @file
* Default theme implementation to format an HTML mail.
*
* Copy this file in your default theme folder to create a custom themed mail.
* Rename it to mimemail-message--[module]--[key].tpl.php to override it for a
* specific mail.
*
* Available variables:
* - $recipient: The recipient of the message
* - $subject: The message subject
* - $body: The message body
* - $css: Internal style sheets
* - $module: The sending module
* - $key: The message identifier
*
* @see template_preprocess_mimemail_message()
*/
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php if ($css): ?>
<style type="text/css">
<!--
<?php print $css ?>
-->
</style>
<?php endif; ?>
</head>
<body id="mimemail-body" <?php if ($module && $key): print 'class="'. $module .'-'. $key .'"'; endif; ?>>
<div id="center">
<div id="main">
<?php print $body ?>
</div>
</div>
</body>
</html>