PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.20
VikAppointments Services Booking Calendar v1.2.20
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / views / caldays / tmpl / default_calendar.php
vikappointments / admin / views / caldays / tmpl Last commit date
default.php 1 month ago default_calendar.php 1 month ago default_create_modal.php 1 month ago default_day.php 1 month ago default_filterbar.php 1 month ago default_modal.php 1 month ago default_sidebar.php 1 month ago index.html 1 month ago
default_calendar.php
326 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 $vik = VAPApplication::getInstance();
15 $config = VAPFactory::getConfig();
16
17 $date_format = $config->get('dateformat');
18
19 $opening = VikAppointments::getOpeningTime();
20 $closing = VikAppointments::getClosingTime();
21
22 $day = $this->calendar->start;
23
24 $cal = $this->calendar->calendar;
25
26 /**
27 * Take the height per hour from the configuration.
28 *
29 * @since 1.7.6
30 */
31 $cell_height_pixel = max(60, $config->getUint('calhourheight', 0));
32
33 /**
34 * Use date string instead of UNIX timestamp.
35 *
36 * @since 1.6.3
37 */
38 $date = JFactory::getDate($day);
39
40 // display only relevant hours
41 $opening['hour'] = $cal->getMinimumHour($opening['hour']);
42
43 if ($opening['hour'] > 0)
44 {
45 // decrease by one in order to have a wider range
46 $opening['hour']--;
47 }
48
49 $closing['hour'] = $cal->getMaximumHour($closing['hour']);
50
51 if ($closing['hour'] < 24)
52 {
53 // increase by one in order to have a wider range
54 $closing['hour']++;
55 }
56
57 $tz = JFactory::getUser()->getTimezone();
58
59 ?>
60
61 <style>
62 table.vap-workday-calendar td {
63 height: <?php echo $cell_height_pixel; ?>px !important;
64 }
65 </style>
66
67 <?php echo $vik->openFieldset($date->format('F Y'), 'form-horizontal'); ?>
68
69 <table class="vap-workday-calendar" cellspacing="0">
70 <thead>
71 <tr>
72 <th width="7%">&nbsp;</th>
73 <?php
74 for ($i = 0; $i < 7; $i++)
75 {
76 ?>
77 <th class="head-date" width="12%">
78 <div data-cell-date="<?php echo $date->format($date_format); ?>">
79 <?php echo $date->format('D d'); ?>
80 </div>
81 </th>
82 <?php
83
84 $date->modify('+1 day');
85 }
86 ?>
87 </tr>
88 </thead>
89
90 <tbody>
91 <?php
92 $end = ($closing['min'] == 0 ? $closing['hour'] - 1 : $closing['hour']);
93 // $end = $closing['hour'];
94 for ($h = $opening['hour']; $h <= $end; $h++)
95 {
96 ?>
97 <tr>
98 <td style="text-align: right;">
99 <?php echo JHtml::fetch('vikappointments.min2time', $h * 60, true); ?>
100 </td>
101 <?php
102 /**
103 * Use date string instead of UNIX timestamp.
104 *
105 * @since 1.6.3
106 */
107 $date = JFactory::getDate($day);
108
109 for ($i = 0; $i < 7; $i++)
110 {
111 $td_class = array();
112
113 $bounds = array();
114
115 /**
116 * Create date by using the current user timezone, because
117 * the calendar wrapper treats the dates in UTC.
118 *
119 * @since 1.7
120 */
121 $_date = JFactory::getDate($date->format('Y-m-d H:i:s'), $tz);
122
123 $_date->modify($h . ':00:00');
124 $bounds[] = $_date->format('Y-m-d H:i:s');
125
126 $_date->modify(($h + 1) . ':00:00');
127 $bounds[] = $_date->format('Y-m-d H:i:s');
128
129 $rects = $cal->getIntersections($bounds[0], $bounds[1]);
130
131 $td_data = array(
132 'cell-from' => $h * 60,
133 'cell-to' => ($h + 1) * 60,
134 'cell-day' => $date->format('N', true) % 7,
135 'cell-date' => $date->format($date_format, true),
136 );
137
138 // calculate divs to display
139 $divs = array();
140
141 if ($rects)
142 {
143 // Iterate the rects as there may be multiple cells within the same block.
144 // For example, there may be the following appointments:
145 // - from 14:00 to 15:30
146 // - from 15:30 to 17:00
147 // So, the closing div of the first appointment and the opening div of
148 // the second appointment should share the same cell.
149 foreach ($rects as $app)
150 {
151 // do not fill if not needed
152 $class = '';
153 $height = '';
154 $bg = '';
155 $label = '&nbsp;';
156 $margin = 0;
157
158 $use_label = false;
159
160 if ($app->startsAt($h) && $app->start(false)->format('Ymd') == $date->format('Ymd'))
161 {
162 $class = 'time-starts';
163 $shift = $app->startHM() - $h * 60;
164 $margin = $shift * ($cell_height_pixel / 60); // height pixel / max minutes (ratio)
165
166 // in case the checkout is at midnight, we need to
167 // return 24 * 60 (1440) in order to calculate the
168 // height properly
169 $end_hm = $app->endH() == 0 && $closing['hour'] == 24 ? 1440 : $app->endHM();
170
171 $class .= ' time-ends';
172 $top = $end_hm - $h * 60;
173
174 if ($app->isSameDay())
175 {
176 $diff = abs($top - $shift);
177 }
178 else
179 {
180 // appointment between 2 days
181 $diff = 24 * 60 - $app->startHM();
182 $class .= ' trim-end';
183 }
184
185 $height = $diff * ($cell_height_pixel / 60); // height pixel / max minutes (ratio)
186 // we don't need to include the border height because it is part of the cell height
187 // $height += ceil($height / $cell_height_pixel) - 1; // includes 1 px for each border that the div covers
188 $height = "height: {$height}px;";
189
190 $use_label = true;
191 }
192 else if (!$app->isSameDay() && $h == 0)
193 {
194 // display the remaining box of an appointment
195 // that started on the previous day.
196 $class = 'time-starts trim-start time-ends';
197 $top = $app->endHM() - $h * 60;
198
199 $height = $top * ($cell_height_pixel / 60); // height pixel / max minutes (ratio)
200 // we don't need to include the border height because it is part of the cell height
201 // $height += ceil($height / $cell_height_pixel) - 1; // includes 1 px for each border that the div covers
202 $height = "height: {$height}px;";
203 }
204 else if ($app->endsAt($h))
205 {
206 $class = 'time-ends';
207 $shift = $app->endHM() - $h * 60;
208 $margin = ($cell_height_pixel - $shift * ($cell_height_pixel / 60)) * -1; // height pixel / max minutes (ratio)
209 }
210 else if ($app->containsAt($h))
211 {
212 $class = 'time-contains';
213 $margin = 0;
214 }
215
216 // get box data through calendar rect handler
217 $data = $app->getDisplayData($use_label);
218
219 $label = $data['label'];
220 unset($data['label']);
221
222 $bg = $data['background'];
223 unset($data['background']);
224
225 // merge app data with cell data
226 $data = array_merge($data, $td_data);
227
228 // push div within the list
229 $divs[] = array(
230 'class' => $class,
231 'height' => $height,
232 'margin' => $margin,
233 'label' => $label,
234 'background' => $bg,
235 'data' => $data,
236 );
237
238 $td_class[] = $class;
239 }
240 }
241 else
242 {
243 $divs[] = array(
244 'class' => 'time-empty',
245 'height' => '',
246 'margin' => 0,
247 'label' => '&nbsp;',
248 'background' => '',
249 'data' => $td_data,
250 );
251
252 $td_class[] = 'time-empty';
253 }
254
255 $td_class = array_unique($td_class);
256
257 if (count($td_class) > 1)
258 {
259 // time-starts + time-ends
260 $td_class = 'time-contains';
261 }
262 else
263 {
264 // use only the specified class
265 $td_class = $td_class[0];
266 }
267
268 ?>
269 <td class="<?php echo $td_class; ?>" style="position: relative;">
270 <?php
271 foreach ($divs as $div)
272 {
273 $data_str = '';
274 foreach ($div['data'] as $k => $v)
275 {
276 if (is_array($v))
277 {
278 $v = implode(',', $v);
279 }
280
281 $data_str .= " data-{$k}=\"{$v}\"";
282 }
283
284 ?>
285 <div
286 <?php echo $data_str; ?>
287 class="<?php echo $div['class']; ?>"
288 style="position: absolute; width:100%;
289 top: <?php echo $div['margin']; ?>px;
290 <?php echo $div['background']; ?>
291 <?php echo $div['height']; ?>"
292 >
293 <div class="time-box-label">
294 <?php echo $div['label']; ?>
295 </div>
296 </div>
297 <?php
298 }
299 ?>
300 </td>
301 <?php
302 $date->modify('+1 day');
303 }
304 ?>
305 </tr>
306 <?php
307 }
308 ?>
309 </tbody>
310 </table>
311
312 <?php echo $vik->closeFieldset(); ?>
313
314 <script>
315
316 jQuery(function($) {
317 $('td.time-empty, th.head-date').on('click', function() {
318 document.adminForm.date.value = $(this).find('div').data('cell-date');
319 document.adminForm.mode.value = 'day';
320
321 document.adminForm.submit();
322 });
323 });
324
325 </script>
326