ILIAS  trunk Revision v11.0_alpha-1838-g59fc79e306b
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilCalendarDayGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
29 {
30  protected array $seed_info = [];
32  protected int $num_appointments = 1;
33  protected string $timezone = 'UTC';
35 
36  public function __construct(ilDate $seed_date)
37  {
39  }
40 
41  public function initialize(int $a_calendar_presentation_type): void
42  {
43  global $DIC;
44 
45  parent::initialize($a_calendar_presentation_type);
46  $this->seed_info = (array) $this->seed->get(IL_CAL_FKT_GETDATE);
47  $this->user_settings = ilCalendarUserSettings::_getInstanceByUserId($this->user->getId());
48  $this->app_colors = new ilCalendarAppointmentColors($this->user->getId());
49  if ($this->user->getTimeZone()) {
50  $this->timezone = $this->user->getTimeZone();
51  }
52  }
53 
54  public function executeCommand(): void
55  {
56  $next_class = $this->ctrl->getNextClass();
57  switch ($next_class) {
58  case "ilcalendarappointmentpresentationgui":
59  $this->ctrl->setReturn($this, "");
60  $this->logger->debug("-ExecCommand - representation of ilDate: this->seed->get(IL_CAL_DATE) = " . $this->seed->get(IL_CAL_DATE));
61  $gui = ilCalendarAppointmentPresentationGUI::_getInstance($this->seed, (array) $this->getCurrentApp());
62  $this->ctrl->forwardCommand($gui);
63  break;
64  case 'ilcalendarappointmentgui':
65  $this->ctrl->setReturn($this, '');
66  $this->tabs_gui->setSubTabActive((string) ilSession::get('cal_last_tab'));
67 
68  // initial date for new calendar appointments
69  $idate = new ilDate($this->initInitialDateFromQuery(), IL_CAL_DATE);
70  $app = new ilCalendarAppointmentGUI($this->seed, $idate, $this->initAppointmentIdFromQuery());
71  $this->ctrl->forwardCommand($app);
72  break;
73 
74  default:
75  $cmd = $this->ctrl->getCmd("show");
76  $this->$cmd();
77  $this->main_tpl->setContent($this->tpl->get());
78  break;
79  }
80  }
81 
86  protected function show(): void
87  {
88  // config
89  $raster = 15;
90  if ($this->user_settings->getDayStart()) {
91  // push starting point to last "slot" of hour BEFORE morning aggregation
92  $morning_aggr = ($this->user_settings->getDayStart() - 1) * 60 + (60 - $raster);
93  } else {
94  $morning_aggr = 0;
95  }
96  $evening_aggr = $this->user_settings->getDayEnd() * 60;
97 
98  $this->tpl = new ilTemplate('tpl.day_view.html', true, true, 'components/ILIAS/Calendar');
99 
101 
102  $bkid = $this->initBookingUserFromQuery();
103  if ($bkid) {
104  $user_id = $bkid;
105  $no_add = true;
106  } elseif ($this->user->getId() == ANONYMOUS_USER_ID) {
107  $user_id = $this->user->getId();
108  $no_add = true;
109  } else {
110  $user_id = $this->user->getId();
111  $no_add = false;
112  }
113  $scheduler = new ilCalendarSchedule($this->seed, ilCalendarSchedule::TYPE_DAY, $user_id);
114  $scheduler->addSubitemCalendars(true);
115  $scheduler->calculate();
116  $daily_apps = $scheduler->getByDay($this->seed, $this->timezone);
117 
118  //display the download files button.
119  if (count($daily_apps)) {
120  $this->view_with_appointments = true;
121  }
122 
123  $hours = $this->parseInfoIntoRaster(
124  $daily_apps,
125  $morning_aggr,
126  $evening_aggr,
127  $raster
128  );
129 
130  $colspan = $this->calculateColspan($hours);
131 
132  $navigation = new ilCalendarHeaderNavigationGUI($this, $this->seed, ilDateTime::DAY);
133  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
134 
135  if (!$no_add) {
136  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
137  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
138  $new_app_url = $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'add');
139 
140  $this->tpl->setCurrentBlock("new_app1");
141  $this->tpl->setVariable(
142  'H_NEW_APP_GLYPH',
143  $this->ui_renderer->render($this->ui_factory->symbol()->glyph()->add($new_app_url))
144  );
145  $this->tpl->parseCurrentBlock();
146 
147  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
148  }
149 
150  $this->tpl->setVariable('NAVIGATION', $navigation->getHTML());
151 
152  $this->tpl->setVariable(
153  'HEADER_DATE',
154  $this->seed_info['mday'] . ' ' . ilCalendarUtil::_numericMonthToString($this->seed_info['mon'], false)
155  );
156  $this->tpl->setVariable(
157  'HEADER_DAY',
158  ilCalendarUtil::_numericDayToString((int) $this->seed_info['wday'], true)
159  );
160  $this->tpl->setVariable('HCOLSPAN', $colspan - 1);
161 
162  $this->tpl->setVariable('TXT_TIME', $this->lng->txt("time"));
163 
164  // show fullday events
165  foreach ($daily_apps as $event) {
166  if ($event['fullday']) {
167  $this->showFulldayAppointment($event);
168  }
169  }
170  $this->tpl->setCurrentBlock('fullday_apps');
171  $this->tpl->setVariable('TXT_F_DAY', $this->lng->txt("cal_all_day"));
172  $this->tpl->setVariable('COLSPAN', $colspan - 1);
173  $this->tpl->parseCurrentBlock();
174 
175  // parse the hour rows
176  foreach ($hours as $numeric => $hour) {
177  if (!($numeric % 60) || ($numeric == $morning_aggr && $morning_aggr) ||
178  ($numeric == $evening_aggr && $evening_aggr)) {
179  if (!$no_add) {
180  $this->tpl->setCurrentBlock("new_app2");
181  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
182  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
183  $this->ctrl->setParameterByClass(
184  'ilcalendarappointmentgui',
185  'idate',
186  $this->seed->get(IL_CAL_DATE)
187  );
188  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'hour', floor($numeric / 60));
189  $this->tpl->setVariable(
190  'NEW_APP_GLYPH',
191  $this->ui_renderer->render($this->ui_factory->symbol()->glyph()->add(
192  $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'add')
193  ))
194  );
195  $this->tpl->parseCurrentBlock();
196  }
197 
198  // aggregation rows
199  if (($numeric == $morning_aggr && $morning_aggr) ||
200  ($numeric == $evening_aggr && $evening_aggr)) {
201  $this->tpl->setVariable('TIME_ROWSPAN', 1);
202  } // rastered hour
203  else {
204  $this->tpl->setVariable('TIME_ROWSPAN', 60 / $raster);
205  }
206 
207  $this->tpl->setCurrentBlock('time_txt');
208 
209  $this->tpl->setVariable('TIME', $hour['txt']);
210  $this->tpl->parseCurrentBlock();
211  }
212 
213  foreach ($hour['apps_start'] as $app) {
214  $this->showAppointment($app);
215  }
216 
217  for ($i = ($colspan - 1); $i > $hour['apps_num']; $i--) {
218  $this->tpl->setCurrentBlock('empty_cell');
219  $this->tpl->setVariable('EMPTY_WIDTH', (100 / ($colspan - 1)) . '%');
220 
221  // last "slot" of hour needs border
222  if ($numeric % 60 == 60 - $raster ||
223  ($numeric == $morning_aggr && $morning_aggr) ||
224  ($numeric == $evening_aggr && $evening_aggr)) {
225  $this->tpl->setVariable('EMPTY_STYLE', ' calempty_border');
226  }
227 
228  $this->tpl->parseCurrentBlock();
229  }
230 
231  $this->tpl->touchBlock('time_row');
232  }
233  }
234 
235  protected function showFulldayAppointment(array $a_app): void
236  {
237  $event_tpl = new ilTemplate('tpl.day_event_view.html', true, true, 'components/ILIAS/Calendar');
238 
239  $event_tpl->setCurrentBlock('fullday_app');
240 
241  $content = $this->getAppointmentShyButton($a_app['event'], (string) $a_app['dstart'], "");
242 
243  $event_tpl->setVariable('EVENT_CONTENT', $content);
244 
245  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
246  $event_tpl->setVariable('F_APP_BGCOLOR', $color);
247  $event_tpl->setVariable('F_APP_FONTCOLOR', ilCalendarUtil::calculateFontColor($color));
248 
249  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
250  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
251  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'app_id', $a_app['event']->getEntryId());
252  $event_tpl->setVariable(
253  'F_APP_EDIT_LINK',
254  $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'edit')
255  );
256 
257  if ($event_html_by_plugin = $this->getContentByPlugins(
258  $a_app['event'],
259  $a_app['dstart'],
260  $content,
261  $event_tpl
262  )) {
263  $body_html = $event_html_by_plugin;
264  } else {
265  $event_tpl->parseCurrentBlock();
266  $body_html = $event_tpl->get();
267  }
268 
269  $this->tpl->setCurrentBlock("content_fd");
270  $this->tpl->setVariable("CONTENT_EVENT", $body_html);
271  $this->tpl->parseCurrentBlock();
272  $this->num_appointments++;
273  }
274 
275  protected function showAppointment(array $a_app): void
276  {
277  $event_tpl = new ilTemplate('tpl.day_event_view.html', true, true, 'components/ILIAS/Calendar');
278  $event_tpl->setCurrentBlock('app');
279  $this->tpl->setVariable('APP_ROWSPAN', $a_app['rowspan']);
280  $time = '';
281  switch ($this->user_settings->getTimeFormat()) {
283  $time = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE, 'H:i', $this->timezone);
284  break;
285 
287  $time = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE, 'h:ia', $this->timezone);
288  break;
289  }
290 
291  $shy = $this->getAppointmentShyButton($a_app['event'], (string) $a_app['dstart'], "");
292 
293  $title = $shy;
294  $content = ($time != "") ? $time . " " . $title : $title;
295  $event_tpl->setVariable('EVENT_CONTENT', $content);
296 
297  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
298  $event_tpl->setVariable('APP_BGCOLOR', $color);
299  $event_tpl->setVariable('APP_COLOR', ilCalendarUtil::calculateFontColor($color));
300  $event_tpl->setVariable('APP_ADD_STYLES', $a_app['event']->getPresentationStyle());
301 
302  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
303  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
304  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'app_id', $a_app['event']->getEntryId());
305  $event_tpl->setVariable('APP_EDIT_LINK', $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'edit'));
306 
307  if ($event_html_by_plugin = $this->getContentByPlugins(
308  $a_app['event'],
309  $a_app['dstart'],
310  $content,
311  $event_tpl
312  )) {
313  $event_html = $event_html_by_plugin;
314  } else {
315  $event_tpl->parseCurrentBlock();
316  $event_html = $event_tpl->get();
317  }
318 
319  $this->tpl->setCurrentBlock("event_nfd");
320  $this->tpl->setVariable("CONTENT_EVENT_NFD", $event_html);
321  $this->tpl->parseCurrentBlock();
322 
323  $this->num_appointments++;
324  }
325 
329  protected function parseInfoIntoRaster(array $daily_apps, int $morning_aggr, int $evening_aggr, int $raster): array
330  {
331  $hours = array();
332  for ($i = $morning_aggr; $i <= $evening_aggr; $i += $raster) {
333  $hours[$i]['apps_start'] = array();
334  $hours[$i]['apps_num'] = 0;
335 
336  switch ($this->user_settings->getTimeFormat()) {
338  if ($morning_aggr > 0 && $i == $morning_aggr) {
339  $hours[$i]['txt'] = sprintf('%02d:00', 0) . ' - ' .
340  sprintf('%02d:00', ceil(($i + 1) / 60));
341  } else {
342  if (!isset($hours[$i]['txt'])) {
343  $hours[$i]['txt'] = sprintf('%02d:%02d', floor($i / 60), $i % 60);
344  } else {
345  $hours[$i]['txt'] .= sprintf('%02d:%02d', floor($i / 60), $i % 60);
346  }
347  }
348  if ($evening_aggr < 23 * 60 && $i == $evening_aggr) {
349  if (!isset($hours[$i]['txt'])) {
350  $hours[$i]['txt'] = ' - ' . sprintf('%02d:00', 0);
351  } else {
352  $hours[$i]['txt'] .= ' - ' . sprintf('%02d:00', 0);
353  }
354  }
355  break;
356 
358  $this->logger->notice('Morning: ' . $morning_aggr . ' and $i:' . $i);
359  if ($morning_aggr > 0 && $i == $morning_aggr) {
360  $hours[$i]['txt'] =
361  date('h a', mktime(0, 0, 0, 1, 1, 2000)) . ' - ' .
362  date('h a', mktime($this->user_settings->getDayStart(), 0, 0, 1, 1, 2000));
363  } else {
364  $hours[$i]['txt'] = date('h a', mktime((int) floor($i / 60), $i % 60, 0, 1, 1, 2000));
365  }
366  if ($evening_aggr < 23 * 60 && $i == $evening_aggr) {
367  if (!isset($hours[$i]['txt'])) {
368  $hours[$i]['txt'] = ' - ' . date('h a', mktime(0, 0, 0, 1, 1, 2000));
369  } else {
370  $hours[$i]['txt'] .= ' - ' . date('h a', mktime(0, 0, 0, 1, 1, 2000));
371  }
372  }
373  break;
374  }
375  }
376 
377  foreach ($daily_apps as $app) {
378  // fullday appointment are not relavant
379  if ($app['fullday']) {
380  continue;
381  }
382  // start hour for this day
383  #21132 #21636
384  if ($app['start_info']['mday'] != $this->seed_info['mday']) {
385  $start = 0;
386  } else {
387  $start = $app['start_info']['hours'] * 60 + $app['start_info']['minutes'];
388  }
389  #21636
390 
391  // end hour for this day
392  #21132
393  if ($app['end_info']['mday'] != $this->seed_info['mday']) {
394  $end = 23 * 60;
395  } elseif ($app['start_info']['hours'] == $app['end_info']['hours']) {
396  $end = $start + $raster;
397  } else {
398  $end = $app['end_info']['hours'] * 60 + $app['end_info']['minutes'];
399  }
400 
401  if ($start < $morning_aggr) {
402  $start = $morning_aggr;
403  }
404  if ($end <= $morning_aggr) {
405  $end = $morning_aggr + $raster;
406  }
407  if ($start > $evening_aggr) {
408  $start = $evening_aggr;
409  }
410  if ($end > $evening_aggr + $raster) {
411  $end = $evening_aggr + $raster;
412  }
413  if ($end <= $start) {
414  $end = $start + $raster;
415  }
416 
417  // map start and end to raster
418  $start = floor($start / $raster) * $raster;
419  $end = ceil($end / $raster) * $raster;
420 
421  $first = true;
422  for ($i = $start; $i < $end; $i += $raster) {
423  if ($first) {
424  $app['rowspan'] = ceil(($end - $start) / $raster);
425  $hours[$i]['apps_start'][] = $app;
426  $first = false;
427  }
428  $hours[$i]['apps_num']++;
429  }
430  }
431  return $hours;
432  }
433 
434  protected function calculateColspan(array $hours): int
435  {
436  $colspan = 1;
437  foreach ($hours as $hour) {
438  $colspan = max($colspan, $hour['apps_num'] + 1);
439  }
440  return max($colspan, 2);
441  }
442 }
calculateColspan(array $hours)
static _getInstance(ilDate $seed, array $a_app)
get singleton instance
static get(string $a_var)
ilCalendarUserSettings $user_settings
const ANONYMOUS_USER_ID
Definition: constants.php:27
static _numericMonthToString(int $a_month, bool $a_long=true, ?ilLanguage $lng=null)
numeric month to string
getContentByPlugins(ilCalendarEntry $a_cal_entry, int $a_start_date, string $a_content, ilTemplate $a_tpl)
parseInfoIntoRaster(array $daily_apps, int $morning_aggr, int $evening_aggr, int $raster)
calculate overlapping hours
__construct(ilDate $seed_date)
static _getInstanceByUserId(int $a_user_id)
static _numericDayToString(int $a_day, bool $a_long=true, ?ilLanguage $lng=null)
showFulldayAppointment(array $a_app)
global $DIC
Definition: shib_login.php:22
const IL_CAL_FKT_DATE
static initDragDrop(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Drag and Drop used in Modules/Survey, Services/Calendar, Services/COPage, Services/Form (Jan 2022)
ilCalendarAppointmentColors $app_colors
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
Administrate calendar appointments.
__construct(Container $dic, ilPlugin $plugin)
static calculateFontColor(string $a_html_color_code)
Calculate best font color from html hex color code.
show()
fill data section protected
getAppointmentShyButton(ilCalendarEntry $a_calendar_entry, string $a_dstart, string $a_title_forced="")
initialize(int $a_calendar_presentation_type)
Presentation day view.
Represents a list of calendar appointments (including recurring events) for a specific user in a give...