Browse Source

code as it existed on rooms.library.upei.ca

master
ppound 4 years ago
commit
84eda95c2d
  1. 1
      .gitignore
  2. 339
      LICENSE.txt
  3. 45
      README.txt
  4. 43
      controller/room_reservations.controller.inc
  5. 345
      controller/room_reservations_calendar.controller.inc
  6. 405
      controller/room_reservations_reservation.controller.inc
  7. BIN
      images/007354-blue-jelly-icon-arrows-arrow-sparkle.png
  8. BIN
      images/Click_here_to_book.png
  9. BIN
      images/clear.png
  10. 1736
      room_reservations.admin.inc
  11. 231
      room_reservations.css
  12. 1597
      room_reservations.inc
  13. 27
      room_reservations.info
  14. 234
      room_reservations.install
  15. 64
      room_reservations.js
  16. 872
      room_reservations.module
  17. 1156
      room_reservations.node.inc
  18. 191
      room_reservations.series.inc
  19. 435
      room_reservations.views_default.inc
  20. 97
      view/room_reservations.view.inc
  21. 387
      view/room_reservations_calendar.view.inc
  22. 594
      view/room_reservations_reservation.view.inc

1
.gitignore vendored

@ -0,0 +1 @@
.idea/

339
LICENSE.txt

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

45
README.txt

@ -0,0 +1,45 @@
-- SUMMARY --
Room Reservations is an application for making and managing room reservations.
It enables users to view a calendar of reserved and open rooms by day, and to
make, modify, and cancel room reservations. Confirmation of reservations and
reminders can be sent to multiple parties by email and SMS text message.
-- REQUIREMENTS --
Token module.
-- INSTALLATION --
Install as usual, see http://drupal.org/node/70151 for further information.
-- CONFIGURATION --
Administrators can configure the module to define the following items:
* application name
* room categories
* rooms
* hours by day when reservations can be made
* reservation policies
* reservation instructions
* SMS wireless network information
* reservation confirmation messages
* reservation reminder messages
* time of day reminders are sent
Detailed instructions for configuring the module can be found at
http://drupal.org/node/1853318.
-- CONTACT --
Current maintainer:
* Bob Humphrey - http://drupal.org/user/560600
-- SPONSOR --
This project has been sponsored by:
William Madison Randall Library
University of North Carolina Wilmington
http://library.uncw.edu/

43
controller/room_reservations.controller.inc

@ -0,0 +1,43 @@
<?php
/**
* @file
* Miscellaneous controller functionality.
*/
/**
* Display a list of the user's current reservations.
*
* @global object $user
* Drupal user object.
* @global type $base_url
* The base URL of the Drupal installation.
*
* @return string
* A list of the user's reservations in HTML format.
*/
function room_reservations_res_list() {
global $user;
global $base_url;
$user_reservations = NULL;
$count = 0;
if ($user->uid) {
// User is logged in.
$user_reservations = _room_reservations_user_reservations();
$count = count($user_reservations);
}
$output .= theme('room_reservations_list', array('user' => $user, 'base_url' => $base_url, 'user_reservations' => $user_reservations, 'count' => $count));
return $output;
}
/**
* Display a page showing the reservation system policies.
*
* @return string
* The policies for the reservation system as entered by the administrator
* using the Display Text configuration page.
*/
function room_reservations_policies() {
$output = check_markup(_room_reservations_get_variable('policies'));
return $output;
}

345
controller/room_reservations_calendar.controller.inc

@ -0,0 +1,345 @@
<?php
/**
* @file
* Calendar controller functionality.
*/
/**
* Display the reservation calendar.
*
* @param int $selected_month
* (optional) The month of the day selected by the user.
* @param int $selected_day
* (optional) The day of the month selected by the user.
*
* @return string
* The page display formatted as HTML.
*/
function room_reservations($selected_month = NULL, $selected_day = NULL) {
// likely no need for this as not used anywhere else; but maybe for external modules
global $yyyymmdd;
// dates are now keyed by Cat ID; but we only need anyone of these to build calendar but make sure its the one which starts earliest
$datesbycat = _room_reservations_dates($selected_month, $selected_day);
$categories = _room_reservations_categories();
// allow other modules to alter the categories
drupal_alter('room_reservations_categories', $categories);
// if no Categories left; we should not bother with the rest of this
if (!count($categories)) {
drupal_set_message(t('There are no configured Room Categories. Please contact the System Administrator'), 'warning');
drupal_goto();
}
$earliest = _room_reservations_earliest_category($categories);
$dates = $datesbycat[$earliest];
// Determine which day has been selected by the user. If the user has entered a url that specifies a day outside of the
// allowable reservation window, then set the current day as the selected day.
$yyyymmdd = $dates[0]['yyyymmdd'];
foreach ($dates as $day) {
if ($day['selected']) {
$yyyymmdd = $day['yyyymmdd'];
}
}
if ($yyyymmdd == $dates[0]['yyyymmdd']) {
$dates[0]['selected'] = TRUE;
$dates[0]['today'] = TRUE;
}
// a bit hacky; but we need to store what the calendar is using for its date so we can use this in theme functions later
//$_SESSION['reservations_current_day'] = $yyyymmdd;
// If the day being displayed is today, only display time slots that are later than the current time minus two hours.
$today_displayed = FALSE;
foreach ($dates as $day) {
if (($day['selected']) && $day['today']) {
$today_displayed = TRUE;
}
}
if ($today_displayed) {
$hours = _room_reservations_hours('limited');
}
else {
$hours = _room_reservations_hours();
}
$_room_reservations_building_hours = _room_reservations_facility_hours();
$display_hours = _room_reservations_hours();
// Determine the open hours (display version) for the date selected by the user.
$building_hours_day = $_room_reservations_building_hours[$yyyymmdd];
$building_hours_display = $building_hours_day['display'];
// For each time slot, determine if the rooms are open or closed.
$building_hours_day = $_room_reservations_building_hours[$yyyymmdd];
$int_first_shift_open = intval($building_hours_day['first_shift_open']);
$int_first_shift_close = intval($building_hours_day['first_shift_close']);
$int_second_shift_open = intval($building_hours_day['second_shift_open']);
$int_second_shift_close = intval($building_hours_day['second_shift_close']);
$open_24 = $building_hours_day['open_24_hours'];
$x = 0;
$buffer = variable_get('room_reservations_before_after_hours', 3) * 100;
foreach ($hours as $time_slot) {
$int_time_slot_time = intval($time_slot['time']);
if ($building_hours_day['open_24_hours']) {
$time_slot['open'] = TRUE;
}
elseif ((($int_time_slot_time >= $int_first_shift_open) && ($int_time_slot_time < $int_first_shift_close)) ||
(($int_time_slot_time >= $int_second_shift_open) && ($int_time_slot_time < $int_second_shift_close))) {
$time_slot['open'] = TRUE;
}
else {
$time_slot['open'] = FALSE;
}
// if not open ALL day let's limit display to start just before first open shift (or 2nd if only one used)
// this assume you must have 1st shift defined and possible 2nd (i.e. can't define only 2nd shift)
if (!$open_24 && $buffer != 300) {
if ($int_first_shift_open < 9999 && ($hours[$x]['time'] < $int_first_shift_open - $buffer)) {
unset($hours[$x]);
}
else {
$hours[$x] = $time_slot;
}
// and do the same for closing
if (isset($hours[$x])) {
if ($int_second_shift_close < 9999) {
if ($hours[$x]['time'] >= $int_second_shift_close + $buffer) {
unset($hours[$x]);
}
}
elseif ($int_first_shift_close < 9999) {
if ($hours[$x]['time'] >= $int_first_shift_close + $buffer) {
unset($hours[$x]);
}
}
}
}
else {
$hours[$x] = $time_slot;
}
$x++;
}
$all_hours = _room_reservations_hours();
$times = _room_reservations_times();
$rooms = _room_reservations_rooms();
// Initialize the $reservations array.
$reservations = array();
foreach ($rooms as $room) {
$room_name = $room['name'];
foreach ($hours as $time_slot) {
$time = $time_slot['time'];
$reservations[$room['nid']][$time] = array(
'time' => $time,
'display' => $time_slot['display'],
'class' => $time_slot['class'],
'id' => '',
'booked' => FALSE,
'start' => FALSE,
'end' => FALSE,
'user' => '',
'name' => '',
);
}
}
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_date', 'value', $yyyymmdd . '%', 'like')
->fieldOrderBy('reservation_time', 'value', 'DESC')
// EFQ respects access so if user does not have access to view a reservation (most likely due to some access module then we will not return a
// reservation for this slot; this means it will not block this slot from being bookable - which is likely worse than being able to
// see the booking title (especially since we have a method to block the title if user really doesn't want anyone to see it)
// so, let's load the reservations as user 1 to make sure we get them all
->addMetaData('account', user_load(1));
$result = $query->execute();
if (isset($result['node'])) {
$result_nids = array_keys($result['node']);
$results = entity_load('node', $result_nids);
foreach ($results as $data) {
$id = $data->nid;
$time = $data->reservation_time[LANGUAGE_NONE][0]['value'];;
$rid = $data->reservation_room[LANGUAGE_NONE][0]['target_id'];
$name = $data->title;
$user_name = $data->name;
$reservations[$rid][$time]['booked'] = TRUE;
$reservations[$rid][$time]['class'] .= ' booked';
$reservations[$rid][$time]['name'] = $name;
$reservations[$rid][$time]['user_name'] = $user_name;
$reservations[$rid][$time]['id'] = $id;
$reservations[$rid][$time]['series_id'] = isset($data->reservation_series_id[LANGUAGE_NONE][0]['value']) ? $data->reservation_series_id[LANGUAGE_NONE][0]['value'] : '';
$reservations[$rid][$time]['user'] = $data->uid;
$reservations[$rid][$time]['blocked'] = isset($data->reservation_block_title[LANGUAGE_NONE][0]['value']) ? $data->reservation_block_title[LANGUAGE_NONE][0]['value'] : 0;
// add rest of slots as booked for the length of this reservation
$length = $data->reservation_length[LANGUAGE_NONE][0]['value'];;
$time_slots = $length / 30;
$reservations[$rid][$time]['slots'] = $time_slots;
$remainder = $length % 30;
if ($remainder > 1) {
$time_slots++;
}
$key = array_search($time, $times);
$x = 2;
while ($x <= $time_slots) {
$key++;
$next_time = $times[$key];
$reservations[$rid][$next_time]['booked'] = TRUE;
if(isset($reservations[$rid][$next_time]['class'])) {
$reservations[$rid][$next_time]['class'] = $reservations[$rid][$next_time]['class'] . ' booked';
}
//$reservations[$rid][$next_time]['class'] .= ' booked';
//$reservations[$rid][$next_time]['class'] = $reservations[$rid][$next_time]['class'] . ' booked';
$x++;
// unclear how we handle wrapping a reservation to the next day; but reservation time slots can't go passed midnight; i.e. slot 47
if ($key == 47) {
break;
}
}
// add in pre/post buffer for setup/takedown (rev 7.x-1.3+)
// - if the slot is part of buffer we add "setup" to class
// - if we don't have admin rights; we also mark it as booked so no one can book in these slots
$category = $categories[$rooms[$rid]['reservations_room_category'][LANGUAGE_NONE][0]['target_id']];
$preslots = $category['prebuffer'] / 30;
$postslots = $category['postbuffer'] / 30;
$startkey = array_search($reservations[$rid][$time]['time'], $times);
$endkey = $startkey + $time_slots;
$k = $startkey - $preslots;
while ($k < $startkey) {
if (!$reservations[$rid][$times[$k]]['booked']) {
$reservations[$rid][$times[$k]]['class'] .= ' setup';
}
$reservations[$rid][$times[$k]]['booked'] = user_access('book over buffer') ? $reservations[$rid][$times[$k]]['booked'] : true;
$k++;
}
$k = $endkey;
while ($k < $endkey + $postslots) {
if (!$reservations[$rid][$times[$k]]['booked']) {
$reservations[$rid][$times[$k]]['class'] .= ' setup';
}
$reservations[$rid][$times[$k]]['booked'] = user_access('book over buffer') ? $reservations[$rid][$times[$k]]['booked'] : true;
$k++;
}
}
}
// Get any room_reservation records for the previous day that might carry over into the selected day.
// Continue to update the $reservation array with that information.
$previous_day = date('Y-m-d', strtotime("$yyyymmdd -1 days"));
$max_length = user_access('create room reservations extended length') ? variable_get('room_reservations_max_length_extended', 120) : variable_get('room_reservations_max_length_standard', 120);
$lhours = _room_reservations_hours();
$rhours = array_reverse($lhours);
$slots = ($max_length / 30) - 1;
$late_times = array();
$search_times = array(
'9999',
'9999',
'9999',
'9999',
'9999',
'9999',
'9999',
);
for ($j = 0; $j < $slots; $j++) {
$hour = $rhours[$j];
$late_times[] = $hour['time'];
$search_times[$j] = $hour['time'];
}
$late_times = array_reverse($late_times);
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_date', 'value', $previous_day . '%', 'like')
->fieldCondition('reservation_time', 'value', $search_times, 'in')
->fieldOrderBy('reservation_time', 'value', 'DESC')
// EFQ respects access so let's load the reservations as user 1 to make sure we get them all
->addMetaData('account', user_load(1));
$result = $query->execute();
if (isset($result['node'])) {
$result_nids = array_keys($result['node']);
$results = entity_load('node', $result_nids);
foreach ($results as $data) {
$id = $data->nid;
$time = $data->reservation_time[LANGUAGE_NONE][0]['value'];
$rid = $data->reservation_room[LANGUAGE_NONE][0]['target_id'];
$length = $data->reservation_length[LANGUAGE_NONE][0]['value'];
//$room_name = $data->room;
$name = $data->title;
$user_name = $data->name;
$time_slots = $length / 30;
$remainder = $length % 30;
if ($remainder > 1) {
$time_slots++;
}
for ($j = 0; $j < (($max_length / 30) - 1); $j++) {
if ($late_times[$j] == $time) {
$carry_over_time_slots = ($time_slots + $j - (($max_length / 30) - 1));
break;
}
}
if ($carry_over_time_slots > 0) {
$reservations[$rid]['0000']['booked'] = TRUE;
$reservations[$rid]['0000']['name'] = $name;
$reservations[$rid]['0000']['user_name'] = $user_name;
$reservations[$rid]['0000']['id'] = $id;
$carry_over_time_slots--;
}
while ($carry_over_time_slots > 0) {
$next_time = $times[$carry_over_time_slots];
$reservations[$rid][$next_time]['booked'] = TRUE;
$carry_over_time_slots--;
}
}
}
$user_reservations = _room_reservations_user_reservations();
$output = '';
$output .= theme('room_reservations', array(
'dates' => $dates,
'categories' => $categories,
'reservations' => $reservations,
'hours' => $hours,
'building_hours' => $_room_reservations_building_hours,
'building_hours_display' => $building_hours_display,
'rooms' => $rooms,
'user_reservations' => $user_reservations));
return $output;
}
function _room_reservations_earliest_category($categories) {
$earliest = 1000;
foreach ($categories as $cat) {
if ($cat['advmin'] < $earliest) {
$earliest = $cat['advmin'];
$result = $cat['nid'];
}
}
return $result;
}
function _room_reservations_get_dates() {
// dates are now keyed by Cat ID; but we only need anyone of these to build calendar but make sure its the one which starts earliest
$datesbycat = _room_reservations_dates($selected_month, $selected_day);
$categories = _room_reservations_categories();
$earliest = _room_reservations_earlist_category($categories);
$dates = $datesbycat[$earliest];
// Determine which day has been selected by the user. If the user has entered a url that specifies a day outside of the
// allowable reservation window, then set the current day as the selected day.
$yyyymmdd = $dates[0]['yyyymmdd'];
foreach ($dates as $day) {
if ($day['selected']) {
$yyyymmdd = $day['yyyymmdd'];
}
}
if ($yyyymmdd == $dates[0]['yyyymmdd']) {
$dates[0]['selected'] = TRUE;
$dates[0]['today'] = TRUE;
}
return $dates;
}

405
controller/room_reservations_reservation.controller.inc

@ -0,0 +1,405 @@
<?php
/**
* @file
* Single reservation controller functionality.
*/
//module_load_include('inc', 'room_reservations', '/view/room_reservations_reservation.view');
/**
* Make a new reservation.
*
* Validates whether the user can make a
* reservation for the requested date, time, and room.
*
* @global object $user
* The Drupal user object.
*
* @param int $month_number
* The month for which the reservation is being made.
* @param int $xday
* The day for which the reservation is being made.
* @param string $time
* The time at which the reservation is beeing made.
* @param int $xroom
* The room that is being reserved.
*
* @return string
* A form that can be used for making a reservation.
*/
function room_reservations_res_add($month_number, $xday, $time, $xroom) {
$res = new Reservation();
$res->monthNumber = $month_number;
$res->day = $xday;
$res->time = $time;
$res->room = $xroom;
$parameter_errors = FALSE;
$output = '';
global $user;
$logged_in = ($user->uid);
$res->userName = ($logged_in) ? $user->name : "";
$res->emailAddresses = _room_reservations_default_email();
if (!$logged_in) {
drupal_set_message(t("You must be logged in to make a reservation."), 'error');
$parameter_errors = TRUE;
}
// Validate date and get day of week, month name, and year.
$dates = _room_reservations_dates();
$reservation_is_for_today = FALSE;
$day_found = FALSE;
foreach ($dates as $day) {
if (($res->monthNumber == $day['month-number']) && ($res->day == $day['day'])) {
$day_found = TRUE;
$month = $day['month'];
$res->year = $day['year'];
$day_of_week = $day['day-of-week'];
$res->displayDate = $day['display'];
$res->date = $day['yyyymmdd'];
$unix_timestamp = strtotime($res->date);
$res->displayDate = date("l, F j, Y", $unix_timestamp);
if ($day['today']) {
$reservation_is_for_today = TRUE;
}
break;
}
}
if (!$day_found) {
drupal_set_message(t("An invalid date has been entered."), 'error');
$parameter_errors = TRUE;
}
else {
// Determine if the building is open.
$_room_reservations_building_hours = _room_reservations_facility_hours();
$building_hours_day = $_room_reservations_building_hours[$res->date];
if (!$building_hours_day['open']) {
drupal_set_message(t("An invalid date has been entered."), 'error');
$parameter_errors = TRUE;
}
}
// Validate time.
$hours = _room_reservations_hours();
$hour_found = FALSE;
foreach ($hours as $time_slot) {
if ($res->time == $time_slot['time']) {
$res->displayTime = $time_slot['display'];
$hour_found = TRUE;
break;
}
}
if (!$hour_found) {
drupal_set_message(t("An invalid time has been entered."), 'error');
$parameter_errors = TRUE;
}
// Determine if the building is open for the time selected.
if ($day_found) {
$building_is_open = FALSE;
$int_time_slot_time = intval($res->time);
$int_first_shift_open = intval($building_hours_day['first_shift_open']);
$int_first_shift_close = intval($building_hours_day['first_shift_close']);
$int_second_shift_open = intval($building_hours_day['second_shift_open']);
$int_second_shift_close = intval($building_hours_day['second_shift_close']);
$open_24 = $building_hours_day['open_24_hours'];
if ($open_24) {
$building_is_open = TRUE;
}
elseif ((($int_time_slot_time >= $int_first_shift_open) &&
($int_time_slot_time < $int_first_shift_close)) ||
(($int_time_slot_time >= $int_second_shift_open) &&
($int_time_slot_time < $int_second_shift_close))) {
$building_is_open = TRUE;
}
else {
$building_is_open = FALSE;
}
if (!$building_is_open) {
drupal_set_message(t("An invalid time has been entered."), 'error');
$parameter_errors = TRUE;
}
}
// If the reservation is being made for the current date, it must be for a
// time that is later than the current time.
if (!$parameter_errors) {
$reservation_date_time = strtotime($res->date . ' ' .
drupal_substr($res->time, 0, 2) . ':' .
drupal_substr($res->time, 2) . ':00');
$now = strtotime(date('Y-m-d H:i:s'));
if ($reservation_date_time < $now) {
drupal_set_message(t("A reservation cannot be made for a time that has already passed."), 'error');
$parameter_errors = TRUE;
}
}
// Validate room.
$rooms = _room_reservations_rooms();
$room_found = FALSE;
foreach ($rooms as $room) {
if ($res->room == $room['name']) {
$res->roomCapacity = $room['capacity'];
$res->roomCategory = $room['category'];
$room_found = TRUE;
break;
}
}
if (!$room_found) {
drupal_set_message(t("An invalid room has been entered."), 'error');
$parameter_errors = TRUE;
}
// Determine if the room and time conflicts with another reservation.
if (!$parameter_errors) {
$conflicts_found = _room_reservations_start_conflicts($res->room, $res->date, $res->time);
if ($conflicts_found) {
$hours = _room_reservations_hours();
foreach ($hours as $individual_hour) {
if ($individual_hour['time'] == $time) {
$display_time = $individual_hour['display'];
break;
}
}
$unix_timestamp = strtotime($res->date);
$display_date = date("F j, Y", $unix_timestamp);
drupal_set_message(t('Room @room has already been reserved for !date at
!time.', array(
'@room' => $res->room,
'!date' => $display_date,
'!time' => $display_time,
)), 'error');
$parameter_errors = TRUE;
}
}
// Determine the valid lengths of time for this reservation.
if (!$parameter_errors) {
$res->validLengths = _room_reservations_valid_lengths($res->room, $res->date, $res->time);
}
// Limit the total number of active user reservations.
$user_reservations = _room_reservations_user_reservations();
$count = count($user_reservations);
$max = variable_get('room_reservations_reservations_per_user', 4);
if ($max) {
if ($count >= $max) {
drupal_set_message(t("You have already made the allowable number of reservations."), 'error');
$parameter_errors = TRUE;
}
}
// Limit the daily number of user reservations.
if ($res->date) {
if (_room_reservations_daily_max_exceeded($res->date)) {
drupal_set_message(t('You have already made the allowable number of reservations for !date.', array('!date' => $res->displayDate)), 'error');
$parameter_errors = TRUE;
}
}
// Show either errors or form.
if ($parameter_errors) {
drupal_goto('room_reservations');
}
else {
$res->length = 0;
$res->name = '';
$res->groupSize = 0;
$res->id = 0;
$res->textmsg = 0;
$res->carrier = 0;
$res->phone = '';
$output .= drupal_get_form('room_reservations_res_form', 'add', $res);
}
return $output;
}
/**
* View an existing reservation.
*
* Determine if the current user has the right to view the requested
* reservation.
*
* @global object $user
* Drupal user object.
*
* @param int $id
* The record key of the requested reservation.
*
* @return string
* A form used for displaying the reservation.
*/
function room_reservations_res_view($id) {
$parameter_errors = FALSE;
$output = '';
// Current user.
global $user;
$logged_in = ($user->uid);
$user_login_name = ($logged_in) ? $user->name : "";
if (!$logged_in) {
drupal_set_message(t("You must be logged in to view reservation details.", 'error'));
$parameter_errors = TRUE;
}
// Get the reservation record.
$res = new Reservation($id);
if (!$res->id) {
drupal_set_message(t("A reservation with this record ID could not be found."), 'error');
$parameter_errors = TRUE;
}
// Format the display date and time; get room capacity.
if ($res->id) {
$res->displayTime = '';
$res->roomCapacity = 0;
$unix_timestamp = strtotime($res->date);
$res->displayDate = date("l, F j, Y", $unix_timestamp);
$hours = _room_reservations_hours();
foreach ($hours as $time_slot) {
if ($res->time == $time_slot['time']) {
$res->displayTime = $time_slot['display'];
break;
}
}
$rooms = _room_reservations_rooms();
foreach ($rooms as $room) {
if ($res->room == $room['name']) {
$res->roomCapacity = $room['capacity'];
$res->roomCategory = $room['category'];
break;
}
}
}
// Determine if the person requesting the record is either the one who made
// the reservation Or an employee that has access to the record.
$current_user_is_owner = FALSE;
if ($res->id) {
if ($res->userName == $user_login_name) {
$current_user_is_owner = TRUE;
}
elseif (_room_reservations_full_access()) {
// Valid user.
}
else {
drupal_set_message(t("You are not allowed to view this reservation record."), 'error');
$parameter_errors = TRUE;
}
}
// If the reservation is for a future date and/or time, it can be updated by
// the person who made the reservation.
$reservation_can_still_be_updated = FALSE;
if ($res->id) {
$reservation_date_time = strtotime($res->date . ' ' . drupal_substr($res->time, 0, 2) . ':' . drupal_substr($res->time, 2) . ':00');
$now = strtotime(date('Y-m-d H:i:s'));
if ($reservation_date_time > $now) {
$reservation_can_still_be_updated = TRUE;
}
}
// Set the operation for the form to either 'view' or 'update'.
$operation = 'view';
if ($res->id) {
if (($current_user_is_owner) && ($reservation_can_still_be_updated)) {
$operation = 'update';
}
}
$res->validLengths = NULL;
if ((!$parameter_errors) && ($operation == 'update')) {
$res->validLengths = _room_reservations_valid_lengths($res->room, $res->date, $res->time, $res->id);
}
// Show either errors or form.
if ($parameter_errors) {
drupal_goto('room_reservations');
}
else {
$res->monthNumber = drupal_substr($res->date, 5, 2);
$res->day = drupal_substr($res->date, 8);
$res->year = drupal_substr($res->date, 0, 4);
$res->textmsg = ($res->textmsg == 'Y') ? 1 : 0;
$output .= drupal_get_form('room_reservations_res_form', $operation, $res);
}
return $output;
}
/**
* Delete a reservation.
*
* Determine if the current user has the right to delete the requested
* reservation.
*
* @global object $user
* Drupal user object.
*
* @param int $id
* The record key of the requested reservation.
*
* @return string
* A form used for deleting the reservation.
*/
function room_reservations_res_delete($id) {
$parameter_errors = FALSE;
$output = '';
// Current user.
global $user;
$logged_in = ($user->uid);
$user_login_name = ($logged_in) ? $user->name : "";
if (!$logged_in) {
drupal_set_message(t("You must be logged in to cancel a reservation."), 'error');
$parameter_errors = TRUE;
}
// Get the reservation record.
$res = new Reservation($id);
if (!$res->id) {
drupal_set_message(t("A reservation with this record ID could not be found."), 'error');
$parameter_errors = TRUE;
}
// Format the display date and time; get room capacity.
if ($res->id) {
$res->displayTime = '';
$res->roomCapacity = 0;
$unix_timestamp = strtotime($res->date);
$res->displayDate = date("l, F j, Y", $unix_timestamp);
$hours = _room_reservations_hours();
foreach ($hours as $time_slot) {
if ($res->time == $time_slot['time']) {
$res->displayTime = $time_slot['display'];
break;
}
}
$rooms = _room_reservations_rooms();
foreach ($rooms as $room) {
if ($res->room == $room['name']) {
$res->roomCapacity = $room['capacity'];
$res->roomCategory = $room['category'];
break;
}
}
}
// Determine if the person requesting the record is either the one who made
// the reservation or an employee that has access to the record.
$current_user_is_owner = FALSE;
if ($res->id) {
if ($res->userName == $user_login_name) {
$current_user_is_owner = TRUE;
}
else {
drupal_set_message(t("This reservation can only be cancelled by the person who made it."), 'error');
$parameter_errors = TRUE;
}
}
// If the reservation is for a future date and/or time, it can be deleted by
// the person who made the reservation.
$reservation_can_still_be_updated = FALSE;
if ($res->id) {
$reservation_date_time = strtotime($res->date . ' ' .
drupal_substr($res->time, 0, 2) . ':' .
drupal_substr($res->time, 2) . ':00');
$now = strtotime(date('Y-m-d H:i:s'));
if ($reservation_date_time > $now) {
$reservation_can_still_be_updated = TRUE;
}
else {
drupal_set_message(t("This reservation can no longer be cancelled."), 'error');
$parameter_errors = TRUE;
}
}
// Show either the validation errors or the form.
if ($parameter_errors) {
drupal_goto('room_reservations');
}
else {
$res->monthNumber = drupal_substr($res->date, 5, 2);
$res->day = drupal_substr($res->date, 8);
$res->year = drupal_substr($res->date, 0, 4);
$output .= drupal_get_form('room_reservations_cancel_form', $res);
}
return $output;
}

BIN
images/007354-blue-jelly-icon-arrows-arrow-sparkle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
images/Click_here_to_book.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
images/clear.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

1736
room_reservations.admin.inc

File diff suppressed because it is too large Load Diff

231
room_reservations.css

@ -0,0 +1,231 @@
/* ----------------------------- ROOM RESERVATIONS ---------------------------- */
#rooms-calendar .slink {
margin-right: 40px;
}
.reservations-block ul {
list-style-image: url(images/bullet.gif);
}
.reservations-block #reservations {
margin-bottom: 5px;
}
#rooms-calendar .room-tabs {
margin: 0 0 0 7px;
padding: 0;
}
#rooms-calendar ul li,
#rooms-calendar ul.menu li,
#rooms-calendar .item-list ul li,
#rooms-calendar li.leaf {
background: none;
padding: 0 0.75em 0.2em 0.75em;
}
#rooms-calendar .room-tabs li {
float: left;
list-style: none;
margin: 0 0 -3px 0;
padding: 2px 3px;
}
#rooms-calendar .room-tabs li a {
background: #dddddd;
border: 1px solid #999999;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
display: block;
-moz-border-radius-topleft: 7px;
-moz-border-radius-topright: 7px;
padding: 3px 5px;
text-decoration: none;
-webkit-border-top-left-radius: 7px;
-webkit-border-top-right-radius: 7px;
}
#rooms-calendar .room-tabs li a.active {
background: #ffffff;
border-bottom: 1px solid #ffffff;
}
#rooms-calendar .panelContainer {
border: 1px solid #999;
clear: left;
}
#rooms-calendar .panelContainer:after {
content: " ";
display: table;
clear: both;
min-height: 20px;
}
#rooms-calendar .panel {
padding: 0 10px;
}
#rooms-calendar #tabbedPanels .date {
clear: both;
margin: 0;
text-align: center;
}
#rooms-calendar #tabbedPanels .hours {
color: #666666;
font-weight: bold;
margin-bottom: 5px;
text-align: center;
}
#rooms-calendar #date-change,
#tabbedPanels #info {
text-align: center;
}
#rooms-calendar .panel .gcolumns .grid-column {
float: left;
}
#rooms-calendar div.grid-column {
max-width: 115px;
}
#rooms-calendar .panel .gcolumns ul {
padding: 0 1px;
}
#rooms-calendar .panel .gcolumns li {
border: 1px solid #dddddd;
font-size: 85%;
height: 1.33em;
line-height: 15px;
list-style-type: none;
margin: -1px auto 0;
padding: 2px 0;
text-align: center;
}
/*#rooms-calendar .panel .gcolumns li.odd {
border-top: 1px solid #999999;
}
*/
#rooms-calendar .panel .gcolumns li.room-info {
border: none;
}
#rooms-calendar .panel .gcolumns li.room-info-heading {
padding-bottom: 5px;
}
#rooms-calendar .panel .gcolumns li.room-info-footer {
padding-top: 5px;
}
#rooms-calendar .panel .gcolumns .hours-column li {
width: 120px;
}
#rooms-calendar .panel .gcolumns .room-column li {
width: 115px;
}
#rooms-calendar .panel .gcolumns li.timeslot {
background-color: #fff;
*height: 1.33em;
*margin-bottom: 2px;
}
#rooms-calendar .panel .gcolumns li.reservable {
background-color: #fff;
}
#rooms-calendar .panel .gcolumns li.open {
background-color: #fff;
}
#rooms-calendar .panel .gcolumns li.booked {
background-color: #ddd;
}
#rooms-calendar .gcolumns li.setup {
background-color: #eee;
}
#rooms-calendar .panel .gcolumns li.closed {
background-color: #d1dfdf;
border: 1px solid #d1dfdf;
}
#rooms-calendar .hide {
display: none;
}
.page-room-reservations .form-item label {
display: inline;
}
#txtmsg-fields {
display: none;
}
#date-change {
margin-bottom:20px;
}
.clear {clear:both;}
/* QTIP Overrides */
.qtip {
box-shadow: -2px 2px 8px rgba(0,0,0,0.3);
}
.qtip canvas {
display: none;
width: 400px;
}
.qtip-link, .qtip-additional-element {
border-bottom: 1px dotted #999;
}
.qtip h4 {
margin: 0px;
margin-top: 0.5em;
font-size: 12px;
color: #999;
font-family: 'AvenirNextLTW01-Regular', Arial;
}
.qtip-tooltip {
font-family: 'AvenirNextLTW01-Regular', Arial;
font-size: 12px;
margin-bottom: 0.5em;
width: 400px;
}
/*! Light tooltip style */
.ui-tooltip-light .ui-tooltip-titlebar,
.ui-tooltip-light .ui-tooltip-content{
border-color: transparent;
color: #333;
}
.ui-tooltip-light .ui-tooltip-content {
background-color: white;
width: 270px !important;
}
.ui-tooltip-light .ui-tooltip-titlebar {
width: 244px !important;
}
#ui-datepicker-div {
z-index:2 !important;
}
#rooms-calendar ul li.reservable:hover, #rooms-calendar ul li.open:hover {
background-color:#FFF;
}

1597
room_reservations.inc

File diff suppressed because it is too large Load Diff

27
room_reservations.info

@ -0,0 +1,27 @@
name = Room Reservations
description = Room reservation booking system.
core = 7.x
package = Other
dependencies[] = token
dependencies[] = entityreference
dependencies[] = field
dependencies[] = views
;dependencies[] = qtip
dependencies[] = date
dependencies[] = date_popup
files[] = room_reservations.inc
; Information added by Drupal.org packaging script on 2015-01-13
version = "7.x-1.2"
core = "7.x"
project = "room_reservations"
datestamp = "1421188081"
; Information added by Drupal.org packaging script on 2016-12-15
version = "7.x-2.x-dev"
core = "7.x"
project = "room_reservations"
datestamp = "1481826785"

234
room_reservations.install

@ -0,0 +1,234 @@
<?php
/**
* Implements hook_schema().
*
* Required Nodes (TODO use Entities:
* - room category (possibly should be a taxonomy)
* - room
* - reservation
*
*/
function room_reservations_schema() {
$schema['room_reservations_variables'] = array(
'description' => '',
'fields' => array(
'id' => array(
'description' => '',
'type' => 'serial',
'not null' => TRUE,
),
'name' => array(
'description' => '',
'type' => 'varchar',
'length' => '128',
'not null' => TRUE,
),
'value' => array(
'description' => '',
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
),
),
'primary key' => array('id'),
'indexes' => array(
'name' => array('name'),
),
);
return $schema;
}
/**
* The information that the module should remove includes:
*
* variables that the module has set using variable_set() or system_settings_form()
* modifications to existing tables
*
* The module should not remove its entry from the {system} table. Database tables defined by hook_schema() will be removed automatically.
*
* NOTE - but our tables are node tables and not created via hook_schema so must be cleaned out here
*
*/
function room_reservations_uninstall() {
/*
db_query("DELETE FROM {node_type} WHERE type LIKE 'room_reservations_%'");
db_query("DELETE FROM {field_config} WHERE field_name LIKE 'rooms_%'");
db_query("DELETE FROM {field_config_instance} WHERE bundle LIKE 'room_reservations_category'");
db_query("DELETE FROM {field_config_instance} WHERE bundle LIKE 'room_reservations_room'");
db_drop_table('{field_data_rooms_room_category}');
db_drop_table('{field_data_rooms_room_capacity}');
db_drop_table('{field_revision_rooms_room_category}');
db_drop_table('{field_revision_rooms_room_capacity}');
db_drop_table('{field_data_reservation_room}');
db_drop_table('{field_revision_reservation_room}'); */
// remove reservation type
db_query("DELETE FROM {node_type} WHERE type LIKE 'room_reservations_%'");
db_query("DELETE FROM {field_config} WHERE field_name LIKE 'reservation%'");
db_query("DELETE FROM {field_config} WHERE field_name IN ('room_category', 'room_capacity')");
db_query("DELETE FROM {field_config_instance} WHERE bundle LIKE 'room_reservations_%'");
// remove our custom fields - this means all RR content will be removed including room nodes
$fields = array(
'reservation_block_title',
'reservation_date',
'reservation_length',
'reservation_repeat_type',
'reservation_repeat_until',
'reservation_room',
'reservation_series_id',
'reservation_time',
'reservations_display_order',
'room_capacity',
'room_category',
);
foreach ($fields as $field) {
db_drop_table('field_data_' . $field);
db_drop_table('field_revision_' . $field);
}
}
/**
* attempt to clean up the mess of field names
*/
function room_reservations_update_7000() {
db_change_field('field_data_room_capacity', 'room_capacity_value', 'reservations_room_capacity_value', array(
'type' => 'int',
'length' => 11,
'description' => 'Number of people the room can accommodate.'));
db_change_field('field_revision_room_capacity', 'room_capacity_value', 'reservations_room_capacity_value', array(
'type' => 'int',
'length' => 11,
'description' => 'Number of people the room can accommodate.'));
db_change_field('field_data_room_category', 'room_category_target_id', 'reservations_room_category_target_id', array(
'type' => 'int',
'length' => 10,
'description' => 'Which category the room is in.'));
db_change_field('field_revision_room_category', 'room_category_target_id', 'reservations_room_category_target_id', array(
'type' => 'int',
'length' => 10,
'description' => 'Which category the room is in.'));
db_change_field('field_data_reservation_display_order', 'reservation_display_order_value', 'reservations_display_order_value', array(
'type' => 'int',
'length' => 11,
'description' => 'Order to display rooms and categories.'));
db_change_field('field_revision_reservation_display_order', 'reservation_display_order_value', 'reservations_display_order_value', array(
'type' => 'int',
'length' => 11,
'description' => 'Order to display rooms and categories.'));
db_rename_table('field_data_room_capacity', 'field_data_reservations_room_capacity');
db_rename_table('field_data_room_category', 'field_data_reservations_room_category');
db_rename_table('field_revision_room_capacity', 'field_revision_reservations_room_capacity');
db_rename_table('field_revision_room_category', 'field_revision_reservations_room_category');
db_rename_table('field_data_reservation_display_order', 'field_data_reservations_display_order');
db_rename_table('field_revision_reservation_display_order', 'field_revision_reservations_display_order');
db_drop_table('field_data_room_reservations_room_capacity');
db_drop_table('field_data_room_reservations_room_category');
db_drop_table('field_data_rooms_room_capacity');
db_drop_table('field_data_rooms_room_category');
db_drop_table('field_revision_room_reservations_room_capacity');
db_drop_table('field_revision_room_reservations_room_category');
db_drop_table('field_revision_rooms_room_capacity');
db_drop_table('field_revision_rooms_room_category');
db_drop_table('field_data_reservation_carrier');
db_drop_table('field_data_reservation_email_addresses');
db_drop_table('field_data_reservation_phone');
db_drop_table('field_data_reservation_txtmsg');
db_drop_table('field_revision_reservation_carrier');
db_drop_table('field_revision_reservation_email_addresses');
db_drop_table('field_revision_reservation_phone');
db_drop_table('field_revision_reservation_txtmsg');
db_update('field_config')
->fields(array(
'field_name' => 'reservations_room_capacity',
))
->condition('field_name', 'room_capacity', '=')
->execute();
db_update('field_config')
->fields(array(
'field_name' => 'reservations_room_category',
))
->condition('field_name', 'room_category', '=')
->execute();
db_update('field_config')
->fields(array(
'field_name' => 'reservations_display_order',
))
->condition('field_name', 'reservation_display_order', '=')
->execute();
db_update('field_config_instance')
->fields(array(
'field_name' => 'reservations_room_capacity',
))
->condition('field_name', 'room_capacity', '=')
->execute();
db_update('field_config_instance')
->fields(array(
'field_name' => 'reservations_room_category',
))
->condition('field_name', 'room_category', '=')
->execute();
db_update('field_config_instance')
->fields(array(
'field_name' => 'reservations_display_order',
))
->condition('field_name', 'reservation_display_order', '=')
->execute();
}
/**
* fix a couple of the Notices - due to incomplete node defs
*/
function room_reservations_update_7001() {
foreach (_room_reservations_installed_fields_room() as $field) {
field_update_field($field);
}
foreach (_room_reservations_installed_instances_room() as $instance) {
$instance['entity_type'] = 'node';
$instance['bundle'] = 'room_reservations_room';
field_update_instance($instance);
}
}
/**
* Add Cateogry field Minimum Advanced Booking,
* Add Cateogry field Setup time,
* Add Cateogry field Takedown time
*/
function room_reservations_update_7002() {
$existing = field_info_field_map();
$create = array(
'reservations_minadvbooking',
'reservations_prebuffer',
'reservations_postbuffer',
);
foreach (_room_reservations_installed_fields_category() as $field) {
if (isset($existing[$field['field_name']])) {
continue;
}
if (in_array($field['field_name'], $create)) {
field_create_field($field);
}
}
foreach (_room_reservations_installed_instances_category() as $instance) {
if (isset($existing[$instance['field_name']])) {
continue;
}
$instance['entity_type'] = 'node';
$instance['bundle'] = 'room_reservations_category';
if (in_array($instance['field_name'], $create)) {
field_create_instance($instance);
}
}
}

64
room_reservations.js

@ -0,0 +1,64 @@
(function ($) {
Drupal.behaviors.room_reservations = {};
Drupal.behaviors.room_reservations.attach = function(context) {
// set default Category tab if one is set in URL anchor
var anchor = window.location.hash;
if (anchor) {
$('.room-tabs a.active').removeClass('active');
$('.room-tabs li a[href=' + anchor + ']').addClass('active');
$('.panel').hide();
$(anchor).show();
}
// show the selected category panel
$('.room-tabs a').click(function() {
$this = $(this);
$('.panel').hide();
$('.room-tabs a.active').removeClass('active');
$this.addClass('active').blur();
var panel = $this.attr('href');
$(panel).fadeIn(250);
return false;
});
// change calendar date displayed
$('#edit-date-datepicker-popup-0').change(function() {
var datebits = $(this).val().split('/');
var formatarr = Drupal.settings.room_reservations.dateformat.split('/');
var dateobj = new Object();
$.each(formatarr, function(index, value) {
dateobj[value] = datebits[index];
});
var val = dateobj.m + '/' + dateobj.d;
var path = window.location.href;
var loc = path.lastIndexOf('room_reservations');
if (loc != -1) {
var end = loc + 17;
var newpath = path.substring(0, end).concat('/');
} else {
var newpath = path.concat('room_reservations/');
}
window.location.href = newpath.concat(val);
});
// show form fields for text message confirmation and reminder
$('#edit-textmsg').each(function() {
if ($(this).attr('checked')) {
$('#txtmsg-fields').slideDown('fast');
}
else {
$('#txtmsg-fields').slideUp('fast');
}
});
$('#edit-textmsg').click(function() {
if ($(this).attr('checked')) {
$('#txtmsg-fields').slideDown('fast');
}
else {
$('#txtmsg-fields').slideUp('fast');
}
});
};
}(jQuery));

872
room_reservations.module

@ -0,0 +1,872 @@
<?php
/**
* @file
* This module creates a room reservation application.
*
* @author Bob Humphrey, Web and Applications Developer, UNCW Randall Library
*/
module_load_include('inc', 'room_reservations', 'room_reservations');
module_load_include('inc', 'room_reservations', 'room_reservations.node');
module_load_include('inc', 'room_reservations', 'room_reservations.views');
module_load_include('inc', 'room_reservations', 'room_reservations.series');
/**
* Implements hook_views_api().
*/
function room_reservations_views_api($module, $api) {
if ($module == 'views' && $api == 'views_default') {
return array('version' => 2);
}
}
/**
* Implements hook_menu().
*/
function room_reservations_menu() {
$app_title = variable_get('room_reservations_title', 'Room Reservations');
$items['admin/config/system/room_reservations'] = array(
'title' => $app_title,
'description' => 'Configure room reservation options',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_NORMAL_ITEM,
'file' => 'room_reservations.admin.inc',
'weight' => 0,
);
$items['admin/config/system/room_reservations/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'access arguments' => array('administer room reservations system'),
'weight' => 10,
);
$items['admin/config/system/room_reservations/settings/general'] = array(
'title' => 'General',
'type' => MENU_DEFAULT_LOCAL_TASK,
'access arguments' => array('administer room reservations system'),
'weight' => 10,
);
$items['admin/config/system/room_reservations/hours'] = array(
'title' => 'Hours',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_default_hours'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 20,
);
$items['admin/config/system/room_reservations/hours/default_hours'] = array(
'title' => 'Default Hours',
'type' => MENU_DEFAULT_LOCAL_TASK,
'access arguments' => array('administer room reservations system'),
'weight' => 10,
);
$items['admin/config/system/room_reservations/hours/daily_hours'] = array(
'title' => 'Daily Hours',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_daily_hours'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 20,
);
$items['admin/config/system/room_reservations/page'] = array(
'title' => 'Display Text',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_page'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 30,
);
/*$items['admin/config/system/room_reservations/sms'] = array(
'title' => 'SMS',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_sms'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 40,
);
$items['admin/config/system/room_reservations/sms/networks'] = array(
'title' => 'Wireless Carriers',
'type' => MENU_DEFAULT_LOCAL_TASK,
'access arguments' => array('administer room reservations system'),
'weight' => 10,
);
$items['admin/config/system/room_reservations/sms/add'] = array(
'title' => 'Add Carrier',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_sms_add'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 20,
);
$items['admin/config/system/room_reservations/sms/delete'] = array(
'title' => 'Delete Carrier',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_sms_delete'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 30,
);
$items['admin/config/system/room_reservations/messages'] = array(
'title' => 'Messages',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_email'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 50,
);
$items['admin/config/system/room_reservations/messages/email'] = array(
'title' => 'Email Messages',
'access arguments' => array('administer room reservations system'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 10,
);
$items['admin/config/system/room_reservations/messages/text'] = array(
'title' => 'SMS Messages',
'page callback' => 'drupal_get_form',
'page arguments' => array('room_reservations_admin_settings_text'),
'access arguments' => array('administer room reservations system'),
'type' => MENU_LOCAL_TASK,
'file' => 'room_reservations.admin.inc',
'weight' => 20,
);
*/
/*
$items['room_reservations/add'] = array(
'title' => 'Reservation Details',
'page callback' => 'room_reservations_res_add',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => '/controller/room_reservations_reservation.controller.inc',
);
$items['room_reservations/view'] = array(
'title' => 'Reservation Details',
'page callback' => 'room_reservations_res_view',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => '/controller/room_reservations_reservation.controller.inc',
);
$items['room_reservations/delete'] = array(
'title' => 'Reservation Details',
'page callback' => 'room_reservations_res_delete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => '/controller/room_reservations_reservation.controller.inc',
); */
$items['room_reservations'] = array(
'title' => variable_get('room_reservations_title', 'Room Reservations'),
'page callback' => 'room_reservations',
'access arguments' => array('view room reservations calendar'),
'type' => MENU_NORMAL_ITEM,
'file' => '/controller/room_reservations_calendar.controller.inc',
);
$items['room_reservations/calendar'] = array(
'title' => 'Calendar',
'access arguments' => array('view room reservations calendar'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 10,
);
$items['room_reservations/policies'] = array(
'title' => 'Policies',
'page callback' => 'room_reservations_policies',
'access arguments' => array('view room reservations calendar'),
'type' => MENU_LOCAL_TASK,
'weight' => 30,
'file' => '/controller/room_reservations.controller.inc',
);
return $items;
}
/**
* Implements hook_init().
().
*/
function room_reservations_init() {
// Add javascript.
drupal_add_js(drupal_get_path('module', 'room_reservations') . '/room_reservations.js');
// Add css.
drupal_add_css(drupal_get_path('module', 'room_reservations') . '/room_reservations.css');
// Prevent this module from caching.
if ((drupal_match_path($_GET['q'], 'room_reservations')) || (drupal_match_path($_GET['q'], 'room_reservations/*'))) {
$GLOBALS['conf']['cache'] = FALSE;
}
}
/**
* Implements hook_permission().
*/
function room_reservations_permission() {
return array(
'administer room reservations system' => array(
'title' => t('Administer the room reservations system'),
'description' => t('Allows administration of room categories, rooms and reservations. Allows administering all system configuration settings.'),
),
'edit any room reservation' => array(
'title' => t('Edit any room reservation'),
'description' => t('Allows editing of all room reservations in the system.'),
),
'delete any room reservation' => array(
'title' => t('Delete any room reservation'),
'description' => t('Allows deleting of any room reservation in the system.'),
),
'create room reservations standard' => array(
'title' => t('Create room reservations as well as edit or cancel your own reservations. Book in advance standard limit.'),
'description' => t('Create room reservations as well as edit or cancel your own reservations'),
),
'create room reservations extended' => array(
'title' => t('Create room reservations as well as edit or cancel your own reservations. Book in advance extended limit.'),
'description' => t('Create room reservations as well as edit or cancel your own reservations'),
),
'bypass minimum advance booking' => array(
'title' => t('Bypass minimum advanced booking limit.'),
'description' => t('Bypass minimum advanced booking limit.'),
),
'bypass reservations limiters' => array(
'title' => t('Bypass number of reservations limiters.'),
'description' => t('Bypass open reservations per user and reservations per day limits.'),
),
'book over buffer' => array(
'title' => t('Allow booking over setup/takedown buffers.'),
'description' => t('Allow user to book over top of the setup/takedown buffer for an existing reservation.'),
),
'create room reservations extended length' => array(
'title' => t('Create extended maximum length room reservations.'),
'description' => t('Create extended length reservations.'),
),
'view room reservations calendar' => array(
'title' => t('View the room reservations calendar'),
'description' => t('Allowed to view the reservations calendar but does not allow creating new reservations.'),
),
);
}
/**
* Implements hook_validate().
*/
function room_reservations_validate($node, $form, &$form_state) {
// If this is not a room reservation or we are not actually creating a new
// node we don't need to check for max reservations so return TRUE.
if ($node->type != 'room_reservations_reservation' ||
$form_state['values']['op'] == 'Cancel Reservation' || !empty($node->nid)) {
return TRUE;
}
// TODO pull into a function as this code is duplicated here and in the form function.
if ($nid = $form['nid']['#value']) {
$res = $form['#node'];
$d = $res->reservation_date['und'][0]['value'];
$yyyymmdd = date('Y-m-d', strtotime($d));
}
// Group name must be 25 characters or less.
if ($node->type == 'room_reservations_reservation' && strlen($node->title) > 25
&& $form_state['values']['op'] == 'Save') {
form_error($form, t('Group name must be less than 25 characters.'));
}
// CREATE NEW.
else {
// Determine if this year or next year.
$yearnow = date('Y');
$absdaynow = date('z');
$absdaydefault = date('z', mktime(0, 0, 0, arg(3), arg(4), $yearnow));
if ($absdaynow > $absdaydefault) {
$year = $yearnow + 1;
}
else {
$year = $yearnow;
}
$yyyymmdd = date('Y-m-d', strtotime($year . '-' . arg(3) . '-' . arg(4)));
}
if (user_access('bypass reservations limiters')) {
return;
}
else {
if (_room_reservations_daily_max_exceeded($yyyymmdd)) {
form_error($form, t('You have exceeded your daily reservation limit.'));
}
if (_room_reservations_user_max_exceeded()) {
form_error($form, t('You have exceeded your total number of reservations allowed.'));
}
}
}
/**
* Implements hook_node_access()
*
* rev 1.3 - change all node access deny to node access ignore so that other modules may better integrate
* - i.e. if DENY is set no other module can override that
*
* NOTE - this hook is not called for user 1
*/
function room_reservations_node_access($nodetype_or_node, $op, $account) {
if (is_object($nodetype_or_node)) {
$nodetype = $nodetype_or_node->type;
}
else {
$nodetype = $nodetype_or_node;
}
switch ($nodetype) {
case 'room_reservations_category':
case 'room_reservations_room':
switch ($op) {
case 'create':
case 'update':
case 'delete':
return user_access('administer room reservations system') ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
}
break;
case 'room_reservations_reservation':
global $user;
// if it is my reservation; do nothing (let Drupal handle as usual)
if ((is_object($nodetype_or_node) && $nodetype_or_node->uid == $user->uid)) {
return NODE_ACCESS_ALLOW;
}
else {
switch ($op) {
case 'create':
// if we are trying to create a reservation let's make sure user hasn't just entered dates via url
// since available lengths takes allowed dates into account; lets just use that
$yyyymmdd = _room_reservations_yyyymmdd(arg(3), arg(4));
$lengths = _room_reservations_valid_lengths(arg(6), $yyyymmdd, arg(5));
if (count($lengths)) {
foreach ($lengths as $length) {
if ($length['is_valid']) {
return (user_access('create room reservations standard') || user_access('create room reservations extended')
|| user_access('administer room reservations system')) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
}
}
}
return NODE_ACCESS_DENY;
case 'update':
return (user_access('administer room reservations system') || user_access('edit any room reservation')) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
case 'delete':
return (user_access('administer room reservations system') || user_access('delete any room reservation')) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
case 'view':
return user_access('administer room reservations system') ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
}
}
break;
}
}
/**
* remove std Node perms for all types associated with Room Reservations
*
* @param mixed $form
* @param mixed $form_state
* @param mixed $form_id
*/
function room_reservations_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) {
foreach ($form['permission'] as $perm => $value) {
if (stristr($perm, 'content') && stristr($perm, 'room_reservations_')) {
unset($form['permission'][$perm]);
}
}
foreach ($form['checkboxes'] as $box => $settings) {
foreach ($settings['#options'] as $index => $option) {
if (stristr($index, 'content') && stristr($index, 'room_reservations_')) {
unset($form['checkboxes'][$box]['#options'][$index]);
}
}
}
}
/**
* Description.
*
* @param mixed $form
* $form
* @param mixed $form_state
* $form_state
* @param mixed $form_id
* $form_id
*/
function room_reservations_form_room_reservations_reservation_node_form_alter(&$form, &$form_state, $form_id) {
// Params either passed in on url - CREATE or pulled from node - EDIT.
// EDIT.
if (user_access('administer site configuration') && isset($_GET['edit']) && $_GET['edit'] == 'standard') {
return;
}
// EDIT
if ($nid = $form['nid']['#value']) {
$res = $form['#node'];
$rid = $res->reservation_room[LANGUAGE_NONE][0]['target_id'];
$d = $res->reservation_date[LANGUAGE_NONE][0]['value'];
$yyyymmdd = date('Y-m-d', strtotime($d));
$t = $res->reservation_time[LANGUAGE_NONE][0]['value'];
}
// CREATE NEW
else {
// if no parameters passed; lets redirect to calendar page
if (!arg(3) && !arg(4)) {
drupal_goto('room_reservations');
}
// determine if this year or next year
$yearnow = date('Y');
$absdaynow = date('z');
$absdaydefault = date('z', mktime(0, 0, 0, arg(3), arg(4), $yearnow));
if ($absdaynow > $absdaydefault) {
$year = $yearnow + 1;
}
else {
$year = $yearnow;
}
$rid = arg(6);
$yyyymmdd = date('Y-m-d', strtotime($year . '-' . arg(3) . '-' . arg(4)));
$d = $yyyymmdd . ' 00:00:00';
$t = arg(5);
}
$room = node_load($rid);
$date = date('l, M d, Y', strtotime($d));
$time = _room_reservations_display_time($t);
$form['reservation_heading']['#type'] = 'markup';
$form['reservation_heading']['#markup'] = '
<h2 class="reservation-h2">' . t('Reservation booking for') . ':</h2><div><strong>' . t('Room') . ': ' . $room->title . '</strong></div>
<div><strong>' . t('Date') . ': ' . $date . '</strong></div>
<div><strong>' . t('Time') . ': ' . $time . '</strong></div><br/>';
$form['reservation_room']['#access'] = 0;
$form['reservation_date']['#access'] = 0;
$form['reservation_time']['#access'] = 0;
$form['reservation_room'][LANGUAGE_NONE]['#default_value'] = $room->nid;
// Date fields are a major pita, setting default does nothing here;
// we need to carry this forward to the node_presave hook
$form['#node']->date_default = $d;
$form['reservation_time'][LANGUAGE_NONE][0]['value']['#default_value'] = $t;
// remove Preview - can likely do this in node def
unset($form['actions']['preview']);
// hide Series ID field
$form['reservation_series_id']['#access'] = FALSE;
// if we are editing; let's do some extra things:
// - disable Repeat options
// - (series) add msg that we are editing a series and link to edit just that entry
if ($nid) {
$form['reservation_repeat_type']['#disabled'] = TRUE;
$form['reservation_repeat_until']['#disabled'] = TRUE;
// not sure why this was here; if req i don't think structure during edit is correct here
/*
if ($form['reservation_repeat_type'][LANGUAGE_NONE][0]['#value'] > 1) {
$form['reservation_repeat_until'][LANGUAGE_NONE][0]['#value'] = $form['reservation_repeat_until'][LANGUAGE_NONE][0]['#default_value']['value'];
}
*/
$form['reservation_repeat_until']['und'][0]['#value'] = $form['reservation_repeat_until']['und'][0]['#default_value']['value'];
// Form alter is hit in/out of form so we alter only in so we don't show
// messages after form is submitted - !count($form_state['input']).
if ($form['reservation_series_id'][LANGUAGE_NONE][0]['value']['#default_value'] && !count($form_state['input'])) {
if (isset($_GET['single'])) {
$series_link = l(t('Click here'), "node/$nid/edit");
drupal_set_message(t('NOTE: you are editing a SINLGE day in a SERIES of reservations. Any changes made here will impact only the reservation
for this day. !link if you want to edit the entire series.', array('!link' => $series_link)), 'warning');
}
else {
$single_link = l(t('Click here'), "node/$nid/edit", array('query' => array('single' => 1)));
drupal_set_message(t('NOTE: you are editing a SERIES of reservations. Any changes made here will impact all reservations in this
series. !link if you only want to edit this specific day in this series.', array('!link' => $single_link)), 'warning');
}
}
// And then parts that have to be here on both passes.
if ($form['reservation_series_id'][LANGUAGE_NONE][0]['value']['#default_value']) {
if (isset($_GET['single'])) {
// Re-label Delete to Cancel Reservation.
$form['actions']['delete']['#value'] = t('Cancel Reservation for This Day');
}
else {
// Remove single node delete and add Delete Series button.
unset($form['actions']['delete']);
$form['actions']['delete_series'] = array(
'#type' => 'submit',
'#value' => t('Cancel Entire Series Reservation'),
'#weight' => 20,
'#submit' => array('_room_reservations_series_delete'),
);
}
}
// And if not part of a series; let's change DELETE button.
if (!$form['reservation_series_id'][LANGUAGE_NONE][0]['value']['#default_value']) {
$form['actions']['delete']['#value'] = t('Cancel Reservation');
}
}
// Only show repeat reservation controls to users with 'Bypass number of reservations limiters' permission.
if (!user_access('Bypass number of reservations limiters')) {
$form['reservation_repeat_type']['#disabled'] = TRUE;
$form['reservation_repeat_until']['#disabled'] = TRUE;
$form['reservation_repeat_type']['#type'] = 'hidden';
$form['reservation_repeat_until']['#type'] = 'hidden';
}
// Always redirect back to reservations calendar page.
$form['actions']['submit']['#submit'][] = 'return_to_reservations_page';
// Limit valid lengths so we have no overlaps.
$validlengths = _room_reservations_valid_lengths($rid, $yyyymmdd, $t);
foreach ($validlengths as $length) {
if ($length['is_valid']) {
$lengths[] = $length['length'];
}
}
foreach ($form['reservation_length'][LANGUAGE_NONE]['#options'] as $slot => &$option) {
if (!in_array($slot, $lengths)) {
unset($form['reservation_length'][LANGUAGE_NONE]['#options'][$slot]);
}
}
$form['reservation_repeat_type'][LANGUAGE_NONE]['#default_value'] = $form['reservation_repeat_type'][LANGUAGE_NONE]['#default_value'] ? $form['reservation_repeat_type'][LANGUAGE_NONE]['#default_value'] : 1;
$form['reservation_repeat_until']['#states'] = array(
'visible' => array(
':input[name="reservation_repeat_type[und]"]' => array('!value' => '1'),
),
);
// CHANGE - empty return not needed.
// return;
}
/**
* Description.
*
* @param mixed $form
* $form
* @param mixed $form_state
* $form_state
* @param mixed $form_id
* $form_id
*/
function room_reservations_form_node_delete_confirm_alter(&$form, &$form_state, $form_id) {
if ($form['#node']->type == 'room_reservations_reservation') {
$form['#submit'][] = 'return_to_reservations_page';
}
// CHANGE - empty return statement not needed here.
// return;
}
/**
* Description.
*
* @param mixed $node
* $node
*/
function room_reservations_node_presave($node) {
switch ($node->type) {
case 'room_reservations_reservation':
if (isset($node->date_default)) {
$node->reservation_date[LANGUAGE_NONE][0]['value'] = $node->date_default;
}
break;
}
}
/**
* Description.
*
* @param mixed &$element
* $element
* @param mixed $form_state
* $form_state
* @param mixed &$context
* $context
*/
function room_reservations_date_popup_process_alter(&$element, &$form_state, &$context) {
if (isset($element['#field']['field_name'])) {
switch ($element['#field']['field_name']) {
case "reservation_repeat_until": {
if (user_access('create room reservations extended')) {
$advancedays = variable_get('room_reservations_advance_extended', 180);
}
else {
$advancedays = variable_get('room_reservations_advance_standard', 14);
}
$element['#datepicker_options'] = array(
'minDate' => '+0d',
'maxDate' => $advancedays . 'D',
);
$element['date'] = date_popup_process_date_part($element);
}
break;
}
}
}
/**
* Description.
*
* @param mixed $form
* $form
* @param mixed $form_state
* $form_state
*/
function return_to_reservations_page($form, &$form_state) {
// Can't set redirect here for DELETE function;
// see delete confirm form alter above
if ($form_state['clicked_button']['#id'] == 'edit-delete') {
return;
}
if(isset($form_state['values']['reservation_room'][LANGUAGE_NONE][0]['target_id'])) {
$rid = $form_state['values']['reservation_room'][LANGUAGE_NONE][0]['target_id'];
$rooms = _room_reservations_rooms();
$categories = _room_reservations_categories();
$room = $rooms[$rid];
$catid = $room['reservations_room_category'][LANGUAGE_NONE][0]['target_id'];
$category = $categories[$catid];
$anchor = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $category['title']));
}
// Need to handle both update and delete case.
$date = (empty($form_state['values']['reservation_date'][LANGUAGE_NONE][0]['value'])) ? NULL : $form['#node']->reservation_date[LANGUAGE_NONE][0]['value'];
if ($date) {
$return = date('n/d', strtotime($date));
$form_state['redirect'] = array('room_reservations/' . $return, array('fragment' => $anchor));
}
}
/**
* Implements hook_theme().
*/
function room_reservations_theme() {
return array(
'room_reservations' => array(
'variables' => array(
'dates',
'categories',
'hours',
'building_hours',
'building_hours_display',
'rooms',
'selected_category',
'user_reservations',
),
'file' => '/view/room_reservations_calendar.view.inc',
),
'room_reservations_descriptions' => array(
'variables' => array('categories, rooms'),
'file' => '/view/room_reservations.view.inc',
),
'room_reservations_list' => array(
'variables' => array('user, base_url, user_reservations, count'),
'file' => '/view/room_reservations.view.inc',
),
);
}
/**
* Implements hook_mail().
*/
function room_reservations_mail($key, &$message, $params) {
global $base_url;
$modified_base_url = str_replace('https', 'http', $base_url);
$headers = array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => '8Bit',
'X-Mailer' => 'Drupal',
);
switch ($key) {
case 'confirmation':
foreach ($headers as $key => $value) {
$message['headers'][$key] = $value;
}
$message['subject'] = _room_reservations_replace_tokens(check_plain(
_room_reservations_get_variable('confirmation_header_text')), $params);
$body = _room_reservations_replace_tokens(check_markup(
_room_reservations_get_variable('confirmation_owner_text')), $params);
$message['body'][] = '<html><body>' . $body . '</body></html>';
break;
case 'notification':
foreach ($headers as $key => $value) {
$message['headers'][$key] = $value;
}
$message['subject'] = _room_reservations_replace_tokens(check_plain(
_room_reservations_get_variable('confirmation_header_text')), $params);
$body = _room_reservations_replace_tokens(check_markup(
_room_reservations_get_variable('confirmation_group_text')), $params);
$message['body'][] = '<html><body>' . $body . '</body></html>';
break;
case 'owner reminder':
foreach ($headers as $key => $value) {
$message['headers'][$key] = $value;
}
$message['subject'] = _room_reservations_replace_tokens(check_plain(
_room_reservations_get_variable('reminder_header_text')), $params);
$body = _room_reservations_replace_tokens(check_markup(
_room_reservations_get_variable('reminder_owner_text')), $params);
$message['body'][] = '<html><body>' . $body . '</body></html>';
break;
case 'group reminder':
foreach ($headers as $key => $value) {
$message['headers'][$key] = $value;
}
$message['subject'] = _room_reservations_replace_tokens(check_plain(
_room_reservations_get_variable('reminder_header_text')), $params);
$body = _room_reservations_replace_tokens(check_markup(
_room_reservations_get_variable('reminder_group_text')), $params);
$message['body'][] = '<html><body>' . $body . '</body></html>';
break;
}
}
/**
* Implements hook_cron().
*/
function xxxroom_reservations_cron() {
// Send reservation reminders.
$send_reminders = _room_reservations_get_variable('send_reminders');
$last_reminders_sent = _room_reservations_get_variable('last_reminders_sent');
$reminder_time = (_room_reservations_get_variable('reminder_time') / 100);
$reminder_cutoff = (_room_reservations_get_variable('reminder_cutoff') / 100) . ':00:00';
$reminders_sent_today = FALSE;
// Reminders are sent once a day. Have they been sent today?
if ($last_reminders_sent) {
if ($last_reminders_sent == date("Y-m-d")) {
$reminders_sent_today = TRUE;
}
}
$current_hour = date("G");
if (($send_reminders) && (!$reminders_sent_today) && ($current_hour >= $reminder_time)) {
$today = date("Y-m-d");
$cutoff = $today . ' ' . $reminder_cutoff;
$tomorrow = date('Y-m-d', strtotime("now +1 days"));
$no_reminder_sent = '0000-00-00 00:00:00';
$not_deleted = 'N';
$sql = "
SELECT *
FROM {room_reservations}
WHERE date = '%s'
AND reminder_date = '%s'
AND create_date < '%s'
AND deleted = '%s'
";
$record_count = 0;
$hours = _room_reservations_hours();
$result = db_query($sql, $tomorrow, $no_reminder_sent, $cutoff, $not_deleted);
if ($result) {
while ($data = db_fetch_object($result)) {
$id = $data->id;
$date = $data->date;
$time = $data->time;
$length = $data->length;
$room = $data->room;
$name = check_plain($data->name);
$group_size = $data->group_size;
$user_name = $data->user_name;
$email_addresses = check_plain($data->email_addresses);
$textmsg = $data->textmsg;
$carrier = $data->carrier;
$phone = check_plain($data->phone);
$record_count++;
$month_name = date("F", strtotime($date));
$month_number = date("n", strtotime($date));
$day = date("j", strtotime($date));
$day_of_week = date("l", strtotime($date));
foreach ($hours as $individual_hour) {
if ($individual_hour['time'] == $time) {
$display_time = $individual_hour['display'];
break;
}
}
// Send email reminders.
$params = array(
'room' => $room,
'month' => $month_name,
'month_number' => $month_number,
'day' => $day,
'day_of_week' => $day_of_week,
'time' => $display_time,
'minutes' => $length,
'name' => $name,
'id' => $id,
'carrier' => $carrier,
'phone' => $phone,
);
$from = check_plain(_room_reservations_get_variable('from_address'));
// Send an email to each person in the group. If the person is the one
// who made the reservation, send the owner reminder message.
// Otherwise, send the group reminder message.
if (drupal_strlen($email_addresses)) {
$to_addresses = explode(',', $email_addresses);
foreach ($to_addresses as $to_address) {
$to_address = trim($to_address);
$pos = strpos($to_address, $user_name);
if ($pos === FALSE) {
$key = 'group reminder';
}
else {
$key = 'owner reminder';
}
$response = drupal_mail('room_reservations', $key, $to_address, language_default(), $params, $from, TRUE);
}
}
// Send a text message if requested.
if ($textmsg == 'Y') {
_room_reservations_send_sms('reminder', $params);
}
// Update the reminder_date field in the db record.
$now = date("Y-m-d H:i");
$sql2 = "UPDATE {room_reservations} SET reminder_date = '%s' WHERE id = %d";
$result2 = db_query($sql2, $now, $id);
}
}
_room_reservations_set_variable('last_reminders_sent', $today);
}
// End code to send reminders.
// Update the building hours records.
$update_building_hours = FALSE;
$today = date("Y-m-d");
$building_hours_update_date = _room_reservations_get_variable('building hours update');
if ($building_hours_update_date) {
if ($building_hours_update_date < $today) {
$update_building_hours = TRUE;
}
}
if (!$building_hours_update_date) {
$update_building_hours = TRUE;
}
if ($update_building_hours) {
_room_reservations_set_variable('building hours update', $today);
$months = _room_reservations_current_months();
$x = 0;
foreach ($months as $month) {
// Delete first month - previous month.
if (!$x) {
$result = _room_reservations_delete_variable('MONTHLY_HOURS_' . $month['YYYY_MM']);
$x++;
}
else {
// Create current three months if they don't exist.
$month_hours = _room_reservations_get_variable('MONTHLY_HOURS_' . $month['YYYY_MM']);
if (!$month_hours) {
_room_reservations_create_mo_hours($month['year'], $month['month'], $month['YYYY_MM']);
}
}
}
}
}

1156
room_reservations.node.inc

File diff suppressed because it is too large Load Diff

191
room_reservations.series.inc

@ -0,0 +1,191 @@
<?php
/**
* Reservation CRUD
*/
/**
* Create REPEATING reservations
*
* @param mixed $node
*/
function room_reservations_insert($node) {
if ($node->type != 'room_reservations_reservation') {
return;
}
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail
if (isset($node->saved)){
return;
}
$rtype = $node->reservation_repeat_type[LANGUAGE_NONE][0]['value'];
$start = $node->reservation_date[LANGUAGE_NONE][0]['value'];
$start_yyyy_mm_dd = date('Y-m-d', strtotime($start));
$end = date('Y-m-d', strtotime($node->reservation_repeat_until[LANGUAGE_NONE][0]['value']));
$time = $node->reservation_time[LANGUAGE_NONE][0]['value'];
$length = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$rid = $node->reservation_room[LANGUAGE_NONE][0]['target_id'];
$day = date('l', strtotime($start));
$msg = '';
switch ($rtype) {
// no repeats
case 1:
return;
// every day until....
case 2:
$skip = '+1 day';
$back = '-1 day';
$msg = t('You have booked every day from %start until %end', array('%start' => $start_yyyy_mm_dd, '%end' => $end));
break;
// this day of the week until..
case 3:
$skip = '+7 day';
$back = '-7 day';
$msg = t('You have booked every %day from %start until %end', array('%day' => $day, '%start' => $start_yyyy_mm_dd, '%end' => $end));
break;
}
// set NID as Series ID for both the primary node and the repeat nodes
$node->reservation_series_id[LANGUAGE_NONE][0]['value'] = $node->nid;
$tmp = clone($node);
unset($tmp->nid, $tmp->vid);
// and must unset default date that we just used in hook_node_presave for the initial node
unset($tmp->date_default);
$date = $start;
$booked = array();
while (strtotime($date) <= strtotime($back, strtotime($end))) {
$date = date('Y-m-d', strtotime($skip, strtotime($date)));
// must check to see if next booking is available
// the first one we don't check as we could not have picked it if it wasn't
if (_room_reservations_is_slot_free($rid, $date, $time, $length)) {
$new = clone($tmp);
$new->reservation_date[LANGUAGE_NONE][0]['value'] = $date . ' 00:00:00'; // added 12:00:00 to fix TZ issues; this is unlikely correct way to do this
$new->saved = true;
node_save($new);
}
else {
$booked[] = $date;
}
}
// lets spit out some useful msgs
// first clear the msg stating we just created the reservation node
drupal_get_messages('status');
drupal_set_message(t('Your reservation series has been booked.'));
drupal_set_message($msg);
if (count($booked)) {
$dates = '<br>' . implode('<br>', $booked);
drupal_set_message(t('The following dates were not booked due to scheduling conflicts: !dates', array('!dates' => $dates)), 'warning');
}
}
// to handle Series edits
function room_reservations_update($node) {
if ($node->type != 'room_reservations_reservation') {
return;
}
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail
if (isset($node->saved)){
return;
}
// if not part of a Series or special single only url; do nothing
if (!isset($node->reservation_series_id[LANGUAGE_NONE][0]) || !($sid = $node->reservation_series_id[LANGUAGE_NONE][0]['value']) || isset($_GET['single'])) {
return;
}
// reservation details
$start = $node->reservation_date[LANGUAGE_NONE][0]['value'];
$end = date('Y-m-d', strtotime($node->reservation_repeat_until[LANGUAGE_NONE][0]['value']));
$time = $node->reservation_time[LANGUAGE_NONE][0]['value'];
$length = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$rid = $node->reservation_room[LANGUAGE_NONE][0]['target_id'];
$day = date('l', strtotime($start));
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
$deleted = array();
if (isset($result['node'])) {
$result_nids = array_keys($result['node']);
$results = entity_load('node', $result_nids);
foreach ($results as $data) {
// for now, only allow changing Title, Blocked title, Length
// first 2 are easy; but to change length we need to check if that period is available and if not delete entry from Series
$data->title = $node->title;
$data->reservation_block_title[LANGUAGE_NONE][0]['value'] = $node->reservation_block_title[LANGUAGE_NONE][0]['value'];
$date = date('Y-m-d', strtotime($data->reservation_date[LANGUAGE_NONE][0]['value']));
if (_room_reservations_is_slot_free($rid, $date, $time, $length)) {
$data->reservation_length[LANGUAGE_NONE][0]['value'] = $node->reservation_length[LANGUAGE_NONE][0]['value'];
$data->saved = true;
node_save($data);
}
// if slot is not available; delete that entry
else {
$deleted[] = $date;
node_delete($data->nid);
}
}
}
// lets spit out some useful msgs
drupal_set_message(t('Your reservation series has been modified.'));
if (count($deleted)) {
$dates = '<br>' . implode('<br>', $deleted);
drupal_set_message(t('The following dates were deleted from the series due to scheduling conflicts: !dates', array('!dates' => $dates)), 'warning');
}
}
function _room_reservations_series_delete($form) {
$sid = $form['#node']->reservation_series_id[LANGUAGE_NONE][0]['value'];
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
if (isset($result['node'])) {
$nids = array_keys($result['node']);
foreach ($nids as $nid) {
node_delete($nid);
}
}
$title = $form['#node']->title;
drupal_set_message(t('The reservation series @title was deleted.', array('@title' => $title)));
drupal_goto('room_reservations');
}
/**
* copy above function for API use only
* - pass SID
*
* @param mixed $sid
*/
function room_reservations_series_delete($sid) {
// grab all reservations in this series
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'room_reservations_reservation')
->fieldCondition('reservation_series_id', 'value', $sid, '=');
$result = $query->execute();
if (isset($result['node'])) {
$nids = array_keys($result['node']);
foreach ($nids as $nid) {
node_delete($nid);
}
}
$res = node_load($sid);
drupal_set_message(t('The reservation series @title was deleted.', array('@title' => $res->title)));
drupal_goto('room_reservations');
}

435
room_reservations.views_default.inc

@ -0,0 +1,435 @@
<?php
/**
* @file
* Bulk export of views_default objects generated by Bulk export module.
*/
/**
* Implements hook_views_default_views().
*/
function room_reservations_views_default_views() {
$views = array();
$view = new view();
$view->name = 'room_reservations';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Room Reservations (default views)';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Room Reservations';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['style_options']['grouping'] = array(
0 => array(
'field' => 'reservations_room_category',
'rendered' => 1,
'rendered_strip' => 0,
),
);
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Entity Reference: Referenced Entity */
$handler->display->display_options['relationships']['reservations_room_category_target_id']['id'] = 'reservations_room_category_target_id';
$handler->display->display_options['relationships']['reservations_room_category_target_id']['table'] = 'field_data_reservations_room_category';
$handler->display->display_options['relationships']['reservations_room_category_target_id']['field'] = 'reservations_room_category_target_id';
$handler->display->display_options['relationships']['reservations_room_category_target_id']['label'] = 'category';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: Body */
$handler->display->display_options['fields']['body']['id'] = 'body';
$handler->display->display_options['fields']['body']['table'] = 'field_data_body';
$handler->display->display_options['fields']['body']['field'] = 'body';
$handler->display->display_options['fields']['body']['label'] = '';
$handler->display->display_options['fields']['body']['element_label_colon'] = FALSE;
/* Field: Content: Capacity */
$handler->display->display_options['fields']['reservations_room_capacity']['id'] = 'reservations_room_capacity';
$handler->display->display_options['fields']['reservations_room_capacity']['table'] = 'field_data_reservations_room_capacity';
$handler->display->display_options['fields']['reservations_room_capacity']['field'] = 'reservations_room_capacity';
$handler->display->display_options['fields']['reservations_room_capacity']['element_type'] = 'span';
/* Field: Content: Category */
$handler->display->display_options['fields']['reservations_room_category']['id'] = 'reservations_room_category';
$handler->display->display_options['fields']['reservations_room_category']['table'] = 'field_data_reservations_room_category';
$handler->display->display_options['fields']['reservations_room_category']['field'] = 'reservations_room_category';
$handler->display->display_options['fields']['reservations_room_category']['label'] = '';
$handler->display->display_options['fields']['reservations_room_category']['exclude'] = TRUE;
$handler->display->display_options['fields']['reservations_room_category']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['reservations_room_category']['settings'] = array(
'link' => 0,
);
/* Sort criterion: Content: Title */
$handler->display->display_options['sorts']['title_1']['id'] = 'title_1';
$handler->display->display_options['sorts']['title_1']['table'] = 'node';
$handler->display->display_options['sorts']['title_1']['field'] = 'title';
$handler->display->display_options['sorts']['title_1']['relationship'] = 'reservations_room_category_target_id';
/* Sort criterion: Content: Title */
$handler->display->display_options['sorts']['title']['id'] = 'title';
$handler->display->display_options['sorts']['title']['table'] = 'node';
$handler->display->display_options['sorts']['title']['field'] = 'title';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
'room_reservations_room' => 'room_reservations_room',
);
/* Display: Room Descriptions */
$handler = $view->new_display('page', 'Room Descriptions', 'page_1');
$handler->display->display_options['path'] = 'room_reservations/rooms';
$handler->display->display_options['menu']['type'] = 'tab';
$handler->display->display_options['menu']['title'] = 'Room Descriptions';
$handler->display->display_options['menu']['weight'] = '20';
$handler->display->display_options['menu']['context'] = 0;
$handler->display->display_options['menu']['context_only_inline'] = 0;
/* Display: My Reservations */
$handler = $view->new_display('page', 'My Reservations', 'page_2');
$handler->display->display_options['defaults']['relationships'] = FALSE;
$handler->display->display_options['defaults']['fields'] = FALSE;
/* Field: Content: Nid */
$handler->display->display_options['fields']['nid']['id'] = 'nid';
$handler->display->display_options['fields']['nid']['table'] = 'node';
$handler->display->display_options['fields']['nid']['field'] = 'nid';
$handler->display->display_options['fields']['nid']['label'] = '';
$handler->display->display_options['fields']['nid']['exclude'] = TRUE;
$handler->display->display_options['fields']['nid']['element_label_colon'] = FALSE;
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = 'Group';
$handler->display->display_options['fields']['title']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['title']['alter']['path'] = 'node/[nid]/edit';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
$handler->display->display_options['fields']['title']['element_type'] = 'span';
$handler->display->display_options['fields']['title']['link_to_node'] = FALSE;
/* Field: Content: Room */
$handler->display->display_options['fields']['reservation_room']['id'] = 'reservation_room';
$handler->display->display_options['fields']['reservation_room']['table'] = 'field_data_reservation_room';
$handler->display->display_options['fields']['reservation_room']['field'] = 'reservation_room';
$handler->display->display_options['fields']['reservation_room']['element_type'] = 'span';
$handler->display->display_options['fields']['reservation_room']['settings'] = array(
'link' => 1,
);
/* Field: Content: Date */
$handler->display->display_options['fields']['reservation_date']['id'] = 'reservation_date';
$handler->display->display_options['fields']['reservation_date']['table'] = 'field_data_reservation_date';
$handler->display->display_options['fields']['reservation_date']['field'] = 'reservation_date';
$handler->display->display_options['fields']['reservation_date']['element_type'] = 'span';
/* Field: Content: Time */
$handler->display->display_options['fields']['reservation_time']['id'] = 'reservation_time';
$handler->display->display_options['fields']['reservation_time']['table'] = 'field_data_reservation_time';
$handler->display->display_options['fields']['reservation_time']['field'] = 'reservation_time';
$handler->display->display_options['fields']['reservation_time']['element_type'] = 'span';
$handler->display->display_options['fields']['reservation_time']['settings'] = array(
'thousand_separator' => '',
'prefix_suffix' => 0,
);
/* Field: Content: Length */
$handler->display->display_options['fields']['reservation_length']['id'] = 'reservation_length';
$handler->display->display_options['fields']['reservation_length']['table'] = 'field_data_reservation_length';
$handler->display->display_options['fields']['reservation_length']['field'] = 'reservation_length';
$handler->display->display_options['fields']['reservation_length']['label'] = 'Booked for';
$handler->display->display_options['fields']['reservation_length']['element_type'] = 'span';
$handler->display->display_options['defaults']['sorts'] = FALSE;
/* Sort criterion: Content: Date (reservation_date) */
$handler->display->display_options['sorts']['reservation_date_value']['id'] = 'reservation_date_value';
$handler->display->display_options['sorts']['reservation_date_value']['table'] = 'field_data_reservation_date';
$handler->display->display_options['sorts']['reservation_date_value']['field'] = 'reservation_date_value';
$handler->display->display_options['defaults']['arguments'] = FALSE;
/* Contextual filter: Content: Author uid */
$handler->display->display_options['arguments']['uid']['id'] = 'uid';
$handler->display->display_options['arguments']['uid']['table'] = 'node';
$handler->display->display_options['arguments']['uid']['field'] = 'uid';
$handler->display->display_options['arguments']['uid']['default_action'] = 'default';
$handler->display->display_options['arguments']['uid']['default_argument_type'] = 'current_user';
$handler->display->display_options['arguments']['uid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['uid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['uid']['summary_options']['items_per_page'] = '25';
$handler->display->display_options['defaults']['filter_groups'] = FALSE;
$handler->display->display_options['defaults']['filters'] = FALSE;
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
'room_reservations_reservation' => 'room_reservations_reservation',
);
/* Filter criterion: Content: Date (reservation_date) */
$handler->display->display_options['filters']['reservation_date_value']['id'] = 'reservation_date_value';
$handler->display->display_options['filters']['reservation_date_value']['table'] = 'field_data_reservation_date';
$handler->display->display_options['filters']['reservation_date_value']['field'] = 'reservation_date_value';
$handler->display->display_options['filters']['reservation_date_value']['operator'] = '>=';
$handler->display->display_options['filters']['reservation_date_value']['form_type'] = 'date_text';
$handler->display->display_options['filters']['reservation_date_value']['default_date'] = 'now';
$handler->display->display_options['path'] = 'room_reservations/list';
$handler->display->display_options['menu']['type'] = 'tab';
$handler->display->display_options['menu']['title'] = 'My Reservations';
$handler->display->display_options['menu']['weight'] = '15';
$handler->display->display_options['menu']['context'] = 0;
$handler->display->display_options['menu']['context_only_inline'] = 0;
$views['room_reservations'] = $view;
/////////////////////////////////////////////
$view = new view();
$view->name = 'manage_reservations';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Manage Reservations';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Manage Reservations';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['access']['perm'] = 'administer room reservations system';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '40';
$handler->display->display_options['style_plugin'] = 'table';
$handler->display->display_options['style_options']['columns'] = array(
'title' => 'title',
'title_2' => 'title',
'title_1' => 'title',
'reservation_date' => 'reservation_date',
'reservation_time' => 'reservation_date',
'reservation_length' => 'reservation_date',
'name' => 'title',
'reservation_repeat_type' => 'reservation_repeat_type',
'reservation_repeat_until' => 'reservation_repeat_type',
);
$handler->display->display_options['style_options']['default'] = '-1';
$handler->display->display_options['style_options']['info'] = array(
'title' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '<br>',
'empty_column' => 0,
),
'title_2' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'title_1' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'reservation_date' => array(
'sortable' => 1,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '<br>',
'empty_column' => 0,
),
'reservation_time' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'reservation_length' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'name' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'reservation_repeat_type' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '<br>',
'empty_column' => 0,
),
'reservation_repeat_until' => array(
'sortable' => 0,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
);
/* Relationship: Content: Author */
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
$handler->display->display_options['relationships']['uid']['table'] = 'node';
$handler->display->display_options['relationships']['uid']['field'] = 'uid';
/* Relationship: Entity Reference: Referenced Entity */
$handler->display->display_options['relationships']['reservation_room_target_id']['id'] = 'reservation_room_target_id';
$handler->display->display_options['relationships']['reservation_room_target_id']['table'] = 'field_data_reservation_room';
$handler->display->display_options['relationships']['reservation_room_target_id']['field'] = 'reservation_room_target_id';
$handler->display->display_options['relationships']['reservation_room_target_id']['label'] = 'room';
/* Relationship: Entity Reference: Referencing entity */
$handler->display->display_options['relationships']['reverse_reservations_room_category_node']['id'] = 'reverse_reservations_room_category_node';
$handler->display->display_options['relationships']['reverse_reservations_room_category_node']['table'] = 'node';
$handler->display->display_options['relationships']['reverse_reservations_room_category_node']['field'] = 'reverse_reservations_room_category_node';
$handler->display->display_options['relationships']['reverse_reservations_room_category_node']['relationship'] = 'reservation_room_target_id';
$handler->display->display_options['relationships']['reverse_reservations_room_category_node']['label'] = 'reservations_room_category';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: Title */
$handler->display->display_options['fields']['title_2']['id'] = 'title_2';
$handler->display->display_options['fields']['title_2']['table'] = 'node';
$handler->display->display_options['fields']['title_2']['field'] = 'title';
$handler->display->display_options['fields']['title_2']['relationship'] = 'reverse_reservations_room_category_node';
$handler->display->display_options['fields']['title_2']['label'] = 'Room Category';
/* Field: Content: Title */
$handler->display->display_options['fields']['title_1']['id'] = 'title_1';
$handler->display->display_options['fields']['title_1']['table'] = 'node';
$handler->display->display_options['fields']['title_1']['field'] = 'title';
$handler->display->display_options['fields']['title_1']['relationship'] = 'reservation_room_target_id';
$handler->display->display_options['fields']['title_1']['label'] = 'Room';
/* Field: Content: Date */
$handler->display->display_options['fields']['reservation_date']['id'] = 'reservation_date';
$handler->display->display_options['fields']['reservation_date']['table'] = 'field_data_reservation_date';
$handler->display->display_options['fields']['reservation_date']['field'] = 'reservation_date';
$handler->display->display_options['fields']['reservation_date']['label'] = 'Reservation Date';
$handler->display->display_options['fields']['reservation_date']['settings'] = array(
'format_type' => 'date_year',
'fromto' => 'both',
'multiple_number' => '',
'multiple_from' => '',
'multiple_to' => '',
);
/* Field: Content: Time */
$handler->display->display_options['fields']['reservation_time']['id'] = 'reservation_time';
$handler->display->display_options['fields']['reservation_time']['table'] = 'field_data_reservation_time';
$handler->display->display_options['fields']['reservation_time']['field'] = 'reservation_time';
$handler->display->display_options['fields']['reservation_time']['label'] = 'Booking Time';
/* Field: Content: Booking Length */
$handler->display->display_options['fields']['reservation_length']['id'] = 'reservation_length';
$handler->display->display_options['fields']['reservation_length']['table'] = 'field_data_reservation_length';
$handler->display->display_options['fields']['reservation_length']['field'] = 'reservation_length';
/* Field: User: Name */
$handler->display->display_options['fields']['name']['id'] = 'name';
$handler->display->display_options['fields']['name']['table'] = 'users';
$handler->display->display_options['fields']['name']['field'] = 'name';
$handler->display->display_options['fields']['name']['relationship'] = 'uid';
$handler->display->display_options['fields']['name']['label'] = 'Booked by';
/* Field: Content: Repeat Type */
$handler->display->display_options['fields']['reservation_repeat_type']['id'] = 'reservation_repeat_type';
$handler->display->display_options['fields']['reservation_repeat_type']['table'] = 'field_data_reservation_repeat_type';
$handler->display->display_options['fields']['reservation_repeat_type']['field'] = 'reservation_repeat_type';
/* Field: Content: Repeat reservation until */
$handler->display->display_options['fields']['reservation_repeat_until']['id'] = 'reservation_repeat_until';
$handler->display->display_options['fields']['reservation_repeat_until']['table'] = 'field_data_reservation_repeat_until';
$handler->display->display_options['fields']['reservation_repeat_until']['field'] = 'reservation_repeat_until';
$handler->display->display_options['fields']['reservation_repeat_until']['settings'] = array(
'format_type' => 'date_year',
'fromto' => 'both',
'multiple_number' => '',
'multiple_from' => '',
'multiple_to' => '',
);
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
'room_reservations_reservation' => 'room_reservations_reservation',
);
/* Filter criterion: Content: Date (reservation_date) */
$handler->display->display_options['filters']['reservation_date_value']['id'] = 'reservation_date_value';
$handler->display->display_options['filters']['reservation_date_value']['table'] = 'field_data_reservation_date';
$handler->display->display_options['filters']['reservation_date_value']['field'] = 'reservation_date_value';
$handler->display->display_options['filters']['reservation_date_value']['exposed'] = TRUE;
$handler->display->display_options['filters']['reservation_date_value']['expose']['operator_id'] = 'reservation_date_value_op';
$handler->display->display_options['filters']['reservation_date_value']['expose']['label'] = 'Reservation Date';
$handler->display->display_options['filters']['reservation_date_value']['expose']['operator'] = 'reservation_date_value_op';
$handler->display->display_options['filters']['reservation_date_value']['expose']['identifier'] = 'reservation_date_value';
$handler->display->display_options['filters']['reservation_date_value']['expose']['remember_roles'] = array(
2 => '2',
1 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
8 => 0,
9 => 0,
10 => 0,
11 => 0,
);
$handler->display->display_options['filters']['reservation_date_value']['form_type'] = 'date_popup';
/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'admin/content/manage-reservations';
$handler->display->display_options['menu']['type'] = 'tab';
$handler->display->display_options['menu']['title'] = 'Manage Reservations';
$handler->display->display_options['menu']['weight'] = '0';
$handler->display->display_options['menu']['context'] = 0;
$handler->display->display_options['menu']['context_only_inline'] = 0;
$views['manage_reservations'] = $view;
return $views;
}

97
view/room_reservations.view.inc

@ -0,0 +1,97 @@
<?php
/**
* @file
* Miscellaneous view functionality.
*/
/**
* Change date form.
*
* Constructor for the small form that appears just above the reservation
* calendar and allows the user to change the date for which reservations
* are displayed on the calendar.
*
* @param array $building_hours
* Contains hrs information for each day for which a reservation can be made.
* @param array $dates
* An array containing information about all the possible days for which a
* reservtion can be made.
* @param array $rooms
* An array representing all of the rooms that can be reserved.
* @param array $categories
* An array of all the room categories.
* @param string $selected_category
* The current category the user has selected, if any.
*/
function room_reservations_select_room_date_form(&$form_state, $building_hours, $dates, $rooms, $categories, $selected_category) {
// Select box options.
$date_options = array();
foreach ($dates as $day) {
$building_hours_day = $building_hours[$day['yyyymmdd']];
if ($building_hours_day['open']) {
$date_options[$day['month-number'] . "/" . $day['day']] = t($day['display']);
}
}
$first = TRUE;
foreach ($rooms as $room) {
$name = $room['name'];
$key = 'room ' . $name;
$capacity = $room['capacity'];
$room_category = $room['category'];
$value = t('@room (capacity: !capacity persons)', array('@room' => $name, '!capacity' => $capacity));
$room_options[$key] = $value;
if ($first) {
$room_default = $key;
$first = FALSE;
}
}
ksort($room_options);
// Defaults.
if ($selected_category) {
$room_default = 'room ' . $selected_category;
}
foreach ($dates as $day) {
if ($day['selected']) {
$date_default = $day['month-number'] . '/' . $day['day'];
break;
}
}
// Form.
$form['date'] = array(
'#title' => t('View a Different Day'),
'#type' => 'select',
'#options' => $date_options,
'#default_value' => $date_default,
'#weight' => 10,
);
$form['room'] = array(
'#title' => t('View a Different Room'),
'#type' => 'select',
'#options' => $room_options,
'#default_value' => $room_default,
'#weight' => 20,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Change Day or Room'),
'#weight' => 30,
);
return $form;
}
/**
* Form submission for the change date form.
*
* @param string $form_id
* Drupal form id.
* @param array $form_state
* Drupal form state object.
*/
function room_reservations_select_room_date_form_submit($form_id, &$form_state) {
$date = $form_state['values']['date'];
$room = drupal_substr($form_state['values']['room'], 5);
$redirect = "room_reservations/" . $date . "/" . $room;
$form_state['redirect'] = $redirect;
}

387
view/room_reservations_calendar.view.inc

@ -0,0 +1,387 @@
<?php
/**
* @file
* Calendar view functionality.
*/
module_load_include('inc', 'room_reservations', '/view/room_reservations.view');
/**
* Theme the room reservation calendar page.
*
* @global object $user
* Drupal user object.
* @global type $base_url
* Application base url.
*
* @param array $dates
* An array containing information about all the possible days for which a
* reservtion can be made.
* @param array $categories
* An array of all the room categories.
* @param array $reservations
* An array representing all the reservations that have been made for the
* day that is being displayed on the calendar.
* @param array $hours
* An array representing every half hour time slot in a single day.
* @param array $building_hours
* A two dimensional array, with the first dimension representing a single
* day for which a reservation can be made, and the second dimension
* representing information about the facility's open hours for that day, such
* as whether the facility is open that day, the number of open shifts,
* open and close hours, and a string that can be used to display the hours
* in a user friendly way.
* @param string $building_hours_display
* A user friendly string of the open hours for the day being displayed
* on the calendar.
* @param array $rooms
* An array representing all of the rooms that can be reserved.
* @param string $selected_category
* The current category the user has selected, if any.
* @param array $user_reservations
* An array representing the current user's reservations for the allowable
* reservation period.
*
* @return string
* The html for displaying the page.
*/
function theme_room_reservations($variables) {
global $user;
global $base_url;
// to support minimum adv booking per category; let's get available dates per cat
$datespercat = _room_reservations_dates(null, null, true);
// pass date format to JS
$format = strtolower(variable_get('room_reservations_picker_format', 'y/m/d'));
drupal_add_js(array('room_reservations' => array('dateformat' => $format)), 'setting');
extract($variables);
// $selected_category inside $variables isn't formed right to be pulled out as is with extract()
$selected_category = NULL;
// User information.
$full_access = FALSE;
$user_login_name = NULL;
if ($user->uid) {
$user_login_name = $user->name;
$full_access = user_access('administer room reservations system') || user_access('edit any room reservation');
}
// Determine which date has been selected by the user.
foreach ($dates as $day) {
if ($day['selected'] == TRUE) {
$day_of_week = $day['day-of-week'];
$month_number = $day['month-number'];
$month = $day['month'];
$xday = $day['day'];
$year = $day['year'];
$yyyymmdd = $day['yyyymmdd'];
}
}
$calendar_text = check_markup(_room_reservations_get_variable('calendar_text'));
$reserve_room_instructions_text = check_markup(_room_reservations_get_variable('reserve_instructions'));
if (!$reserve_room_instructions_text) {
$reserve_room_instructions_text = t('To reserve a room, click on the desired time/day in the calendar below. You will be asked to login.');
}
// Room reservations container.
$output = "<div id='rooms-calendar'>";
$output .= "<div id='tabbedPanels'>";
// Info box - user reservations, maps, link to policies.
$output .= "<div id='info'><div>$calendar_text</div>
<div><img id='arrow' src='" . base_path() . drupal_get_path('module', 'room_reservations') . "/images/007354-blue-jelly-icon-arrows-arrow-sparkle.png' />
<span id='start'>" . $reserve_room_instructions_text . '</span></div></div>';
// Calendar date.
$date = format_date(strtotime($month . ' ' . $xday . ', ' . $year), 'custom', 'l, F d, Y');
$output .= '<h3 class="date">' . t('Reservation Calendar') . '</h3>' .
'<div class="hours">' . $date . '&nbsp;&nbsp;' . $building_hours_display . '</div>';
// add new Day Selector as popup calendar since we now allow going out up to 6 months rather than 15 days.
$form = drupal_get_form('room_reservations_admin_date_picker', $yyyymmdd);
$output .= '<div id="date-change">' . drupal_render($form) . '</div>';
// Reservation calendar grid:
//
// Each block on the grid is assigned one (or more) of the following classes:
//
// closed - the building is closed;
// booked - the building is open and the time slot has been reserved;
// open - the building is open, the time slot has not been reserved, but the user must login to reserve the time slot;
// reservable - the building is open, the time slot has not been reserved and the user is able to reserve the time slot.
// setup - buffer zones added before/after bookings to allow for setup/takedown (per category)
//
// Tabs.
$output .= "<ul class='room-tabs'>";
$i = 0;
foreach ($categories as $category) {
// Set the first tab as active
// @todo: use JS to set active based on anchor
$active = ($i == 0) ? " class='active'" : "";
$i++;
$id = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $category['title']));
$output .= '<li><a' . $active . " href='#" . $id . "'>" . $category['title'] . '</a></li>';
}
// Panel container.
$output .= "</ul><div class='panelContainer'>";
// If the user is logged in, the class for each unbooked time slot is 'reservable'. If the user is not logged in, the class is 'open'.
// Only logged in users can click a block of time to open the reservation form.
$unbooked_class = ($user->uid) ? 'reservable' : 'open';
// Create a tab for each room category. Each tab contains a grid of time slots and rooms.
$i = 0;
foreach ($categories as $category) {
$table = array();
// Show the first tab and hide all others.
if (!$selected_category) {
$show = ($i == 0) ? 'show' : 'hide';
$i++;
}
else {
$show = ($category['title'] == $selected_category) ? 'show' : 'hide';
}
$id = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $category['title']));
$r = 0; $c = 0;
// Date and building hours.
$flipped = variable_get('room_reservations_calendar_flipped', 0);
$orientclass = $flipped ? 'orient-horiz' : 'orient-vert';
// this is the main DIV wrapper for the "table" within each Category
$output .= '<div id="' . $id . '" class="panel ' . $show . '"><div class="gcolumns' . ' ' . $orientclass . '">';
$table[$r][$c] = "<li class='room-info'>" . t('Room') . '</li>';
$r++;
$table[$r][$c] = "<li class='room-info room-info-heading'>" . t('Capacity') . '</li>';
$r++;
// Available hours column.
foreach ($hours as $time_slot) {
$time_display = ($time_slot['class'] == 'odd') ? t($time_slot['display']) : "";
$table[$r][$c] = "<li class='" . $time_slot['class'] . " timeslot' time='" . $time_slot['time'] . "' " . '>' . $time_display . '</li>';
$r++;
}
$table[$r][$c] = "<li class='room-info room-info-footer'>" . t('Room') . '</li>';
$r++;
$table[$r][$c] = "<li class='room-info'>" . t('Capacity') . '</li>';
$r++;
// Count the number of rooms in the selected category.
$rooms_per_category = 0;
foreach ($rooms as $room) {
$rid = $room['nid'];
if ($room['reservations_room_category'][LANGUAGE_NONE][0]['target_id'] == $category['nid']) {
$rooms_per_category++;
}
}
// Column for each room in the category.
foreach ($rooms as $room) {
$rid = $room['nid'];
$room_name = $room['title'];
$room_link = l($room_name, 'node/' . $rid);
$room_desc = $room['body'] ? $room['body'][LANGUAGE_NONE][0]['safe_value'] : "";
// use qtip if we have it
if (module_exists('qtip')) {
$room_info = '<span class="qtip-link"><span class="qtip-tooltip">' . $room_desc . '</span>' . $room_link . '</span>';
}
else {
$room_info = $room_link;
}
if ($room['reservations_room_category'][LANGUAGE_NONE][0]['target_id'] == $category['nid']) {
$c++; $r = 0;
// Room name, capacity.
//$output .= '<div class="grid-column room-column"><ul>';
//$output .= '<li class="room-info">' . $room_info . '</li>';
$table[$r][$c] = '<li class="room-info">' . $room_info . '</li>';
$r++;
$table[$r][$c] = "<li class='room-info room-info-heading'>" . $room['reservations_room_capacity'][LANGUAGE_NONE][0]['value'] . '</li>';
// Populate each time slot.
foreach ($hours as $time_slot) {
$r++;
$time = $time_slot['time'];
$open = $time_slot['open'];
// lets use slot class from reservation if it is set
$slotclass = isset($reservations[$rid][$time_slot['time']]['class']) ? $reservations[$rid][$time_slot['time']]['class'] : $time_slot['class'];
// to support min adv booking per cat; let's simply mark all slots as closed for dates not availble to this user for this cat
if (!isset($datespercat[$category['nid']][$yyyymmdd])) {
$open = false;
}
// Determine if the building is open or closed for this time slot.
if ($open) {
//$booked_class = ($reservations[$rid][$time]['booked']) ? 'booked' : $unbooked_class;
$booked_class = ($reservations[$rid][$time]['booked']) ? '' : $unbooked_class;
}
else {
$booked_class = 'closed';
}
// The time slot can be reserved by the current user.
$viewable_class = '';
$widthclass = '';
if ($booked_class == 'reservable' &&
(user_access('create room reservations standard') || user_access('create room reservations extended') || user_access('administer room reservations system'))) {
$link = l(
'<img src="' . base_path() . drupal_get_path('module', 'room_reservations') . '/images/clear.png" />',
'node/add/room-reservations-reservation/' . $month_number . '/' . $xday . '/' . $time_slot['time'] . '/' . $rid,
array('html' => true)
);
$viewable = '';
}
// The time slot can be reserved by the current user, but the user must login first.
elseif ($booked_class == 'open') {
$link = "<a href='" . $base_url . "/user/login?destination=node/add/room-reservations-reservation/" . $month_number . "/" . $xday . "/" .
$time_slot['time'] . "/" . $rid . "'><img src='" . base_path() . drupal_get_path('module', 'room_reservations') .
"/images/clear.png' /></a>";
$viewable = '';
}
elseif ($booked_class == 'closed') {
$link = '';
}
else {
// The time slot has a reservation that can be edited by the current user.
$reservation = node_load($reservations[$rid][$time]['id']);
$viewable_class = node_access('update', $reservation) ? 'viewable' : '';
//$viewable_class = (($full_access) || ($reservations[$rid][$time]['user'] == $user->uid)) ? 'viewable' : '';
if ($viewable_class == 'viewable') {
$id = $reservations[$rid][$time]['id'];
$link = $id ? l($reservations[$rid][$time]['name'], 'node/' . $id . '/edit',
array('attributes' => array(
'title' => $reservations[$rid][$time]['name'],
'class' => 'booking-span')
)
) : '';
}
// The time slot has a reservation that cannot be viewed by the current user. and we are NOT allowed to see the Title
else if (isset($reservations[$rid][$time]['blocked']) && $reservations[$rid][$time]['blocked']) {
$link = t('Booked');
}
// The time slot has a reservation that cannot be edited by the current user. but we are allowed to see the Title
else {
$link = $reservations[$rid][$time]['name'];
}
$slots = isset($reservations[$rid][$time]['slots']) ? $reservations[$rid][$time]['slots'] : '';
$widthclass = $slots ? 'colspan' . $reservations[$rid][$time]['slots'] : '';
}
// allow other modules to modify the $link
drupal_alter('room_reservations_link', $link, $reservations[$rid][$time]);
// allow other modules adding a custom class to slots
$custom_class = '';
drupal_alter('room_reservations_custom_class', $custom_class, $reservations[$rid][$time]);
// add div wrapper to display better
$link = $link ? '<div class="booking-span">' . $link . '</div>' : '';
// we used book class to determine if linked or not; which we needed for pre/post slots as well as actual reservation slots
// but we don't want to show booked class now for the slots which are just buffer slots
if (stristr($slotclass, 'setup')) {
$booked_class = '';
}
$table[$r][$c] = "<li class='" . $slotclass . ' ' . $booked_class . ' ' . $custom_class . ' ' . $viewable_class . ' ' . $widthclass. "'>" . $link . "</li>";
}
// Room name and capacity.
$r++;
$table[$r][$c] = '<li class="room-info">' . $room_info . '</li>';
$r++;
$table[$r][$c] = '<li class="room-info">' . $room['reservations_room_capacity'][LANGUAGE_NONE][0]['value'] . '</li>';
}
}
// remove extra table labels based on admin setting
$compressed = false;
if (variable_get('room_reservations_compressed_labels', 0)) {
$compressed = true;
}
// dump our table contents in std or flipped orientation
if ($flipped) {
$table = _room_reservations_transpose($table);
$m = $r;
$n = $c;
}
else {
$m = $c;
$n = $r;
}
for ($x = 0; $x <= $m; $x++){
if ($flipped && $compressed && ($x == 1 || $x == $m || $x == $m - 1)) continue;
$output .= "<div class='grid-column hours-column'><ul>";
for ($y = 0; $y <= $n; $y++) {
if (!$flipped && $compressed && ($y == 1 || $y == $n || $y == $n - 1)) continue;
$output .= $table[$y][$x];
}
$output .= '</ul></div>';
}
// end of main DIV wrapper for "table"
$output .= '</div></div>';
}
// end of panelContainer that holds all tables for all Categories
$output .= '</div>';
$output .= '<div class="clear"></div></div>';
$output .= '</div>';
return $output;
}
function room_reservations_admin_date_picker($form, &$form_state) {
$yyyymmdd = $form_state['build_info']['args'][0];
$parts = explode('-', $yyyymmdd);
if (user_access('create room reservations extended')) {
$advancedays = variable_get('room_reservations_advance_extended', 180);
}
else {
$advancedays = variable_get('room_reservations_advance_standard', 14);
}
$yearnow = date('Y');
$absdaynow = date('z');
$absdaydefault = date('z', mktime(0, 0, 0, $parts[1], $parts[2], $yearnow));
if ($absdaynow > $absdaydefault) {
$yeardefault = $yearnow + 1;
}
else {
$yeardefault = $yearnow;
}
$format = str_replace('y', 'Y', strtolower(variable_get('room_reservations_picker_format', 'y/m/d')));
$form['date'] = array(
'#type' => 'date_popup',
'#default_value' => $yeardefault . '-' . $parts[1] . '-' . $parts[2] . ' 00:00:00',
'#date_type' => DATE_DATETIME,
'#date_timezone' => date_default_timezone(),
'#date_format' => $format,
'#date_increment' => 1,
'#date_year_range' => '-0:+1',
'#datepicker_options' => array(
'minDate' => '+0d',
'maxDate' => $advancedays -1 . 'D',
)
);
$form['#after_build'][] = '_room_reservations_admin_date_picker_afterbuild';
return $form;
}
function _room_reservations_admin_date_picker_afterbuild($form, &$form_state) {
$form['date']['date']['#title'] = '';
$form['date']['date']['#description'] = t('click in box to select date');
return $form;
}
function _room_reservations_transpose($array) {
array_unshift($array, null);
return call_user_func_array('array_map', $array);
}

594
view/room_reservations_reservation.view.inc

@ -0,0 +1,594 @@
<?php
/**
* @file
* Single reservation view functionality.
*/
/**
* Form constructor for the reservation form.
*
* @param string $operation
* The operation being performed using the form: add, update, view.
* @param Reservation $res
* A reservation object that contains all the details related to the
* reservation being made, updated, or viewed.
*/
function room_reservations_res_form(&$form_state, $operation, $res) {
$reserve_form_instructions_text = check_markup(_room_reservations_get_variable('reserve_form_instructions'));
$room_reservations_group_size = variable_get('room_reservations_group_size', 0);
$sms_option = _room_reservations_get_variable('sms_option');
if (($operation == 'add') || ($operation == 'update')) {
// Options for number of persons in group, from 2 to room capacity.
$number_persons_options = array();
for ($x = 2; $x <= $res->roomCapacity; $x++) {
$number_persons_options[$x] = $x;
}
// Valid lengths of time.
$length_options = array();
foreach ($res->validLengths as $valid_length) {
if ($valid_length['is_valid']) {
$length_option = $valid_length['length'];
$length_options[$length_option] = $length_option . ' ' . t('minutes');
}
}
}
if (drupal_strlen($res->phone) == 10) {
$display_phone = drupal_substr($res->phone, 0, 3) . '-' .
drupal_substr($res->phone, 3, 3) . '-' .
drupal_substr($res->phone, 6);
}
else {
$display_phone = '';
}
// Form definition.
if ($operation === 'add') {
$form['instructions'] = array(
'#title' => t('Patron'),
'#value' => t($reserve_form_instructions_text),
'#weight' => 0,
);
}
if ($operation === 'update') {
$form['delete_top'] = array(
'#type' => 'submit',
'#value' => t('Cancel My Reservation'),
'#weight' => 4,
);
}
$form['details'] = array(
'#title' => t('Details'),
'#type' => 'fieldset',
'#weight' => 5,
);
$form['details']['room'] = array(
'#title' => t('Room'),
'#type' => 'item',
'#value' => t('@room (capacity: !capacity persons)',
array('@room' => $res->room, '!capacity' => $res->roomCapacity)),
'#weight' => 20,
);
$form['details']['display_date'] = array(
'#title' => t('Date'),
'#type' => 'item',
'#value' => t($res->displayDate),
'#weight' => 25,
);
$form['details']['time'] = array(
'#title' => t('Time'),
'#type' => 'item',
'#value' => t($res->displayTime),
'#weight' => 30,
);
if ($operation == 'add') {
$form['details']['length'] = array(
'#title' => t('Length'),
'#type' => 'radios',
'#options' => $length_options,
'#required' => TRUE,
'#weight' => 35,
);
}
elseif ($operation == 'update') {
$form['details']['length'] = array(
'#title' => t('Length'),
'#type' => 'radios',
'#options' => $length_options,
'#default_value' => $res->length,
'#required' => TRUE,
'#weight' => 35,
);
}
else {
$form['details']['length'] = array(
'#title' => t('Length'),
'#type' => 'item',
'#value' => $res->length,
'#weight' => 35,
);
}
if (($operation == 'add') || ($operation == 'update')) {
$form['details']['group_name'] = array(
'#title' => t('Group name'),
'#type' => 'textfield',
'#description' => t('Identifies your group on the reservation calendar.
14 character limit.'),
'#default_value' => $res->name,
'#maxlength' => 14,
'#size' => 14,
'#required' => TRUE,
'#weight' => 40,
);
}
else {
$form['details']['group_name'] = array(
'#title' => t('Group name'),
'#type' => 'item',
'#value' => $res->name,
'#weight' => 40,
);
}
if ($room_reservations_group_size) {
if ($operation == 'add') {
$form['details']['group_size'] = array(
'#title' => t('Size of the group'),
'#type' => 'radios',
'#options' => $number_persons_options,
'#required' => TRUE,
'#weight' => 45,
);
}
elseif ($operation == 'update') {
$form['details']['group_size'] = array(
'#title' => t('Size of the group'),
'#type' => 'radios',
'#options' => $number_persons_options,
'#default_value' => $res->groupSize,
'#required' => TRUE,
'#weight' => 45,
);
}
else {
$form['details']['group_size'] = array(
'#title' => t('Size of the group'),
'#type' => 'item',
'#value' => $res->groupSize,
'#weight' => 45,
);
}
}
if (_room_reservations_full_access()) {
$form['details']['user_name'] = array(
'#title' => t('User name'),
'#type' => 'item',
'#value' => $res->userName,
'#weight' => 55,
);
}
$form['reminders'] = array(
'#title' => t('Reminders'),
'#type' => 'fieldset',
'#weight' => 60,
);
if ($sms_option) {
if (($operation == 'add') || ($operation == 'update')) {
$form['reminders']['textmsg'] = array(
'#title' => t('I want to receive my confirmation and reminder as a text
message.'),
'#type' => 'checkbox',
'#return_value' => 1,
'#default_value' => $res->textmsg,
'#weight' => 65,
);
$form['reminders']['textmsg_fields_start'] = array(
'#value' => '<div id="txtmsg-fields">',
'#weight' => 66,
);
$form['reminders']['phone'] = array(
'#title' => t('Phone number'),
'#type' => 'textfield',
'#maxlength' => 15,
'#size' => 15,
'#default_value' => $display_phone,
'#weight' => 70,
);
$carriers = _room_reservations_carriers();
$form['reminders']['carrier'] = array(
'#title' => t('Carrier'),
'#type' => 'select',
'#options' => $carriers,
'#default_value' => $res->carrier,
'#weight' => 75,
);
$form['reminders']['charges'] = array(
'#value' => '<div class="form-item">' .
t('NOTE: Carrier charges may apply if your cell phone service
plan does not include free text messaging.') . '</div>',
'#weight' => 80,
);
$form['reminders']['testmsg_fields_end'] = array(
'#value' => '</div>',
'#weight' => 85,
);
}
}
$reminder_columns = 60;
if (($operation == 'add') || ($operation == 'update')) {
$form['reminders']['email_addresses'] = array(
'#title' => t('Email Addresses'),
'#type' => 'textarea',
'#default_value' => $res->emailAddresses,
'#description' => t('Reservation confirmation and reminder will be sent
to any email addresses entered here. Separate addresses with a
comma.'),
'#cols' => $reminder_columns,
'#rows' => 1,
'#weight' => 90,
);
}
else {
$form['reminders']['email_addresses'] = array(
'#title' => t('Email Addresses'),
'#type' => 'item',
'#value' => $res->emailAddresses,
'#weight' => 90,
);
}
if ($operation == 'add') {
$form['add'] = array(
'#type' => 'submit',
'#value' => t('Save My Reservation'),
'#weight' => 100,
);
}
elseif ($operation == 'update') {
$form['update'] = array(
'#type' => 'submit',
'#value' => t('Update My Reservation'),
'#weight' => 100,
);
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Cancel My Reservation'),
'#weight' => 101,
);
}
$form['id'] = array(
'#type' => 'value',
'#value' => $res->id,
);
$form['month_number'] = array(
'#type' => 'value',
'#value' => $res->monthNumber,
);
$form['day'] = array(
'#type' => 'value',
'#value' => $res->day,
);
$form['year'] = array(
'#type' => 'value',
'#value' => $res->year,
);
$form['time_number'] = array(
'#type' => 'value',
'#value' => $res->time,
);
$form['room_name'] = array(
'#type' => 'value',
'#value' => $res->room,
);
$form['category'] = array(
'#type' => 'value',
'#value' => $res->category,
);
$form['yyyymmdd'] = array(
'#type' => 'value',
'#value' => $res->date,
);
$form['user_name_hold'] = array(
'#type' => 'value',
'#value' => $res->userName,
);
return $form;
}
/**
* Form validation for the reservation form.
*
* @param string $form_id
* Drupal form id.
* @param array $form_state
* Drupal form state object.
*/
function room_reservations_res_form_validate($form_id, &$form_state) {
// When a user is filling out the form to reserve a room, it is possible that
// before she can submit the form, someone else will complete a reservation
// for that same room, same date, and at least part of the same time period.
// If that should occur, and the user has requested a length of time that
// is no longer available, Drupal automatically creates the following error:
// 'An illegal choice has been detected. Please contact the site
// administrator.' Since this message is somewhat alarming to the user and
// not very informative, it is replaced in this function with a more
// descriptive message.
$errors = drupal_get_messages();
foreach ($errors as $type => $id) {
foreach ($id as $message) {
// Loop through individual messages, looking for ones to remove or
// replace.
if (room_reservations_rewrite_error($message) === FALSE) {
drupal_set_message($message, $type);
}
elseif (room_reservations_rewrite_error($message) !== TRUE) {
drupal_set_message(room_reservations_rewrite_error($message), $type);
}
}
}
// Validate email addresses.
$email_addresses = trim($form_state['values']['email_addresses']);
if (drupal_strlen($email_addresses)) {
$valid_addresses = TRUE;
$list_items = explode(',', $email_addresses);
foreach ($list_items as $address) {
if (!valid_email_address(trim($address))) {
$valid_addresses = FALSE;
}
}
if (!$valid_addresses) {
form_set_error('email_addresses', t('Email Addresses contains an invalid
email address.'));
}
}
if ((!drupal_strlen($email_addresses)) &&
(!$form_state['values']['textmsg'])) {
$default_sms_option = _room_reservations_get_variable('sms_option');
if ($default_sms_option) {
form_set_error('email_addresses', t('Your email address or phone number is
required.'));
}
else {
form_set_error('email_addresses', t('Your email address is
required.'));
}
}
// Text message information.
if ($form_state['values']['textmsg']) {
$phone = $form_state['values']['phone'];
$phone_number = preg_replace('/[^\d]/', '', $phone);
if (drupal_strlen($phone_number) <> 10) {
form_set_error('phone', t('Ten digit phone number is required
when receiving confirmation by text message.'));
}
if (!$form_state['values']['carrier']) {
form_set_error('carrier', t('Carrier is required
when receiving confirmation by text message.'));
}
}
}
/**
* Form submission for the reservation form.
*
* @param string $form_id
* Drupal form id.
* @param array $form_state
* Drupal form state object.
*/
function room_reservations_res_form_submit($form_id, &$form_state) {
$id = $form_state['values']['id'];
$month_number = $form_state['values']['month_number'];
$day = $form_state['values']['day'];
$year = $form_state['values']['year'];
$time = $form_state['values']['time_number'];
$length = $form_state['values']['length'];
$room = $form_state['values']['room_name'];
$group_name = $form_state['values']['group_name'];
$group_size = $form_state['values']['group_size'];
$user_name = $form_state['values']['user_name_hold'];
$category = $form_state['values']['category'];
$yyyymmdd = $form_state['values']['yyyymmdd'];
$email_addresses = trim($form_state['values']['email_addresses']);
$textmsg_checkbox = $form_state['values']['textmsg'];
$carrier = $form_state['values']['carrier'];
$phone_full = $form_state['values']['phone'];
$phone = preg_replace('/[^\d]/', '', $phone_full);
if ($textmsg_checkbox) {
$textmsg = 'Y';
}
else {
$textmsg = 'N';
$carrier = 0;
$phone = '';
}
if ($time < 1000) {
$time = str_pad($time, 4, '0', STR_PAD_LEFT);
}
$hours = _room_reservations_hours();
foreach ($hours as $individual_hour) {
if ($individual_hour['time'] == $time) {
$display_hour = $individual_hour['display'];
break;
}
}
$day_of_week = date("l", strtotime($yyyymmdd));
$month_name = date("F", strtotime($yyyymmdd));
// Add.
if ($form_state['clicked_button']['#value'] == t('Save My Reservation')) {
$result = db_query("INSERT INTO {room_reservations} (date, time, length, room, name, group_size, user_name, email_addresses, create_date, textmsg, carrier, phone )
VALUES ('%s', '%s', %d, '%s', '%s', %d, '%s', '%s', '%s', '%s', %d, '%s')",
$yyyymmdd, $time, $length, $room, $group_name, $group_size, $user_name, $email_addresses, date('Y-m-d H:i:s', REQUEST_TIME), $textmsg, $carrier, $phone);
// Send a confirmation email or text message.
$id = db_last_insert_id('room_reservations', 'id');
$params = array(
'room' => $room,
'month' => $month_name,
'month_number' => $month_number,
'day' => $day,
'day_of_week' => $day_of_week,
'time' => $display_hour,
'minutes' => $length,
'name' => $group_name,
'id' => $id,
'carrier' => $carrier,
'phone' => $phone,
);
$from = _room_reservations_get_variable('from_address');
if ($result) {
drupal_set_message(t('Your group study room reservation has been made.'));
// Send an email to each person in the group. If the person is the one
// who made the reservation, send the confirmation message. Otherwise,
// send the notification message.
if (drupal_strlen($email_addresses)) {
$to_addresses = explode(',', $email_addresses);
foreach ($to_addresses as $to_address) {
$to_address = trim($to_address);
$pos = strpos($to_address, $user_name);
if ($pos === FALSE) {
$key = 'notification';
}
else {
$key = 'confirmation';
}
$response = drupal_mail(
'room_reservations', $key, $to_address, language_default(),
$params, $from, TRUE);
}
}
// If requested, send a text message confirmation to the person who made
// the reservation.
if ($textmsg == 'Y') {
_room_reservations_send_sms('confirmation', $params);
}
}
else {
drupal_set_message(t('Your group study room reservation could not be
made.'), 'error');
}
$redirect = "room_reservations/" . $month_number . "/" . $day . "/" . $category;
$form_state['redirect'] = $redirect;
}
// Update.
elseif ($form_state['clicked_button']['#value'] ==
t('Update My Reservation')) {
$result = db_query("
UPDATE {room_reservations}
SET length = %d,
name = '%s',
group_size = %d,
email_addresses = '%s',
update_date = '%s',
textmsg = '%s',
carrier = %d,
phone = '%s'
WHERE id = %d", $length, $group_name, $group_size, $email_addresses, date('Y-m-d H:i:s', REQUEST_TIME), $textmsg, $carrier, $phone, $id);
if ($result) {
drupal_set_message(t('Your group study room reservation has been
updated.'));
}
else {
drupal_set_message(t('Your group study room reservation could not be
updated.'), 'error');
}
$redirect = "room_reservations/" . $month_number . "/" . $day . "/" . $category;
$form_state['redirect'] = $redirect;
}
elseif ($form_state['clicked_button']['#value'] == t('Cancel My Reservation')) {
$redirect = "room_reservations/delete/" . $id;
$form_state['redirect'] = $redirect;
}
}
/**
* Form constructor for the delete reservation form.
*
* @param Reservation $res
* A reservation object that contains all the details related to the
* reservation being deleted.
*/
function room_reservations_cancel_form(&$form_state, $res) {
$room_capacity = $res->roomCapacity;
// Form definition.
$form['room'] = array(
'#title' => t('Room'),
'#type' => 'item',
'#value' => t('@room (capacity: !capacity persons)', array('@room' => $res->room, '!capacity' => $room_capacity)),
'#weight' => 10,
);
$form['display_date'] = array(
'#title' => t('Date'),
'#type' => 'item',
'#value' => t($res->displayDate),
'#weight' => 20,
);
$form['time'] = array(
'#title' => t('Time'),
'#type' => 'item',
'#value' => t($res->displayTime),
'#weight' => 30,
);
$form['length'] = array(
'#title' => t('Length'),
'#type' => 'item',
'#value' => t('!length minutes', array('!length' => $res->length)),
'#weight' => 40,
);
$form['group_name'] = array(
'#title' => t('Group name'),
'#type' => 'item',
'#value' => $res->name,
'#weight' => 50,
);
$form['id'] = array(
'#type' => 'value',
'#value' => $res->id,
);
$form['month_number'] = array(
'#type' => 'value',
'#value' => $res->monthNumber,
);
$form['day'] = array(
'#type' => 'value',
'#value' => $res->day,
);
$form['category'] = array(
'#type' => 'value',
'#value' => $res->roomCategory,
);
$form['user_name_hold'] = array(
'#type' => 'value',
'#value' => $res->userName,
);
return confirm_form($form,
t('Cancel'), 'room_reservations/' . $res->monthNumber . '/' . $res->day . '/' . $res->roomCategory,
t('Are you sure you want to cancel this reservation? This action cannot be undone.'),
t('Cancel My Reservation'),
t("Don't Cancel My Reservation")
);
}
/**
* Form submission for the delete reservation form.
*
* @param string $form_id
* Drupal form id.
* @param array $form_state
* Drupal form state object.
*/
function room_reservations_cancel_form_submit($form_id, &$form_state) {
$id = $form_state['values']['id'];
$month_number = $form_state['values']['month_number'];
$day = $form_state['values']['day'];
$category = $form_state['values']['category'];
// Delete.
if ($form_state['clicked_button']['#value'] == t('Cancel My Reservation')) {
$result = db_query("UPDATE {room_reservations} SET deleted = '%s', update_date = '%s' WHERE id = %d", 'Y', date('Y-m-d H:i:s', REQUEST_TIME), $id);
if ($result) {
drupal_set_message(t('Your group study room reservation has been cancelled.'));
}
else {
drupal_set_message(t('Your group study room reservation could not be cancelled.'), 'error');
}
}
$redirect = "room_reservations/" . $month_number . "/" . $day . "/" . $category;
$form_state['redirect'] = $redirect;
}
Loading…
Cancel
Save