ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilCalendarDayGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2017 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
14 include_once('./Services/Calendar/classes/class.ilDate.php');
15 include_once('./Services/Calendar/classes/class.ilCalendarUtil.php');
16 include_once('./Services/Calendar/classes/class.ilCalendarHeaderNavigationGUI.php');
17 include_once('./Services/Calendar/classes/class.ilCalendarUserSettings.php');
18 include_once('./Services/Calendar/classes/class.ilCalendarAppointmentColors.php');
19 include_once './Services/Calendar/classes/class.ilCalendarViewGUI.php';
20 
21 
23 {
24  protected $seed_info = array();
25  protected $user_settings = null;
26 
30  protected $lng;
31 
35  protected $ctrl;
36 
40  protected $tabs_gui;
41 
45  protected $tpl;
46 
47  protected $num_appointments = 1;
48 
49  protected $timezone = 'UTC';
50 
54  protected $user;
55 
59  protected $ui;
60 
64  protected $toolbar;
65 
74  public function __construct(ilDate $seed_date)
75  {
76  parent::__construct($seed_date, ilCalendarViewGUI::CAL_PRESENTATION_DAY);
77 
78  $this->seed_info = $this->seed->get(IL_CAL_FKT_GETDATE);
79 
80  $this->user_settings = ilCalendarUserSettings::_getInstanceByUserId($this->user->getId());
81  $this->app_colors = new ilCalendarAppointmentColors($this->user->getId());
82 
83  $this->timezone = $this->user->getTimeZone();
84  }
85 
92  public function executeCommand()
93  {
95  $tpl = $this->tpl;
96 
97  $next_class = $ilCtrl->getNextClass();
98  switch ($next_class) {
99  case "ilcalendarappointmentpresentationgui":
100  $this->ctrl->setReturn($this, "");
101  include_once("./Services/Calendar/classes/class.ilCalendarAppointmentPresentationGUI.php");
102  $this->logger->debug("-ExecCommand - representation of ilDate: this->seed->get(IL_CAL_DATE) = " . $this->seed->get(IL_CAL_DATE));
104  $this->ctrl->forwardCommand($gui);
105  break;
106  case 'ilcalendarappointmentgui':
107  $this->ctrl->setReturn($this, '');
108  $this->tabs_gui->setSubTabActive($_SESSION['cal_last_tab']);
109 
110  // initial date for new calendar appointments
111  $idate = new ilDate($_REQUEST['idate'], IL_CAL_DATE);
112 
113  include_once('./Services/Calendar/classes/class.ilCalendarAppointmentGUI.php');
114  $app = new ilCalendarAppointmentGUI($this->seed, $idate, (int) $_GET['app_id']);
115  $this->ctrl->forwardCommand($app);
116  break;
117 
118  default:
119  $cmd = $this->ctrl->getCmd("show");
120  $this->$cmd();
121  $tpl->setContent($this->tpl->get());
122  break;
123  }
124  return true;
125  }
126 
133  protected function show()
134  {
138  global $DIC;
139 
140  $ui_factory = $DIC->ui()->factory();
141  $renderer = $DIC->ui()->renderer();
142 
143  $lng = $this->lng;
145 
146 
147  // config
148  $raster = 15;
149  if ($this->user_settings->getDayStart()) {
150  // push starting point to last "slot" of hour BEFORE morning aggregation
151  $morning_aggr = ($this->user_settings->getDayStart() - 1) * 60 + (60 - $raster);
152  } else {
153  $morning_aggr = 0;
154  }
155  $evening_aggr = $this->user_settings->getDayEnd() * 60;
156 
157 
158  $this->tpl = new ilTemplate('tpl.day_view.html', true, true, 'Services/Calendar');
159 
160  include_once('./Services/YUI/classes/class.ilYuiUtil.php');
162 
163  if (isset($_GET["bkid"])) {
164  $user_id = $_GET["bkid"];
165  $no_add = true;
166  } elseif ($ilUser->getId() == ANONYMOUS_USER_ID) {
167  $user_id = $ilUser->getId();
168  $no_add = true;
169  } else {
170  $user_id = $ilUser->getId();
171  $no_add = false;
172  }
173  include_once('Services/Calendar/classes/class.ilCalendarSchedule.php');
174  $this->scheduler = new ilCalendarSchedule($this->seed, ilCalendarSchedule::TYPE_DAY, $user_id);
175  $this->scheduler->addSubitemCalendars(true);
176  $this->scheduler->calculate();
177  $daily_apps = $this->scheduler->getByDay($this->seed, $this->timezone);
178 
179  //display the download files button.
180  if (count($daily_apps)) {
181  $this->view_with_appointments = true;
182  }
183 
184  $hours = $this->parseInfoIntoRaster(
185  $daily_apps,
186  $morning_aggr,
187  $evening_aggr,
188  $raster
189  );
190 
191  $colspan = $this->calculateColspan($hours);
192 
193  $navigation = new ilCalendarHeaderNavigationGUI($this, $this->seed, ilDateTime::DAY);
194  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
195 
196  // add milestone link
197  include_once('Services/Calendar/classes/class.ilCalendarSettings.php');
198  $settings = ilCalendarSettings::_getInstance();
199 
200  if (!$no_add) {
201  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
202  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
203  $new_app_url = $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'add');
204 
205  if ($settings->getEnableGroupMilestones()) {
206  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
207  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
208  $new_ms_url = $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'addMilestone');
209 
210  $this->tpl->setCurrentBlock("new_ms");
211  $this->tpl->setVariable('DD_ID', $this->seed->get(IL_CAL_UNIX));
212  $this->tpl->setVariable('DD_TRIGGER', $renderer->render($ui_factory->glyph()->add()));
213  $this->tpl->setVariable('URL_DD_NEW_APP', $new_app_url);
214  $this->tpl->setVariable('TXT_DD_NEW_APP', $this->lng->txt('cal_new_app'));
215  $this->tpl->setVariable('URL_DD_NEW_MS', $new_ms_url);
216  $this->tpl->setVariable('TXT_DD_NEW_MS', $this->lng->txt('cal_new_ms'));
217  $this->tpl->parseCurrentBlock();
218  } else {
219  $this->tpl->setCurrentBlock("new_app1");
220  $this->tpl->setVariable('H_NEW_APP_GLYPH', $renderer->render($ui_factory->glyph()->add($new_app_url)));
221  $this->tpl->parseCurrentBlock();
222  }
223 
224  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
225  }
226 
227  $this->tpl->setVariable('NAVIGATION', $navigation->getHTML());
228 
229  $this->tpl->setVariable('HEADER_DATE', $this->seed_info['mday'] . ' ' . ilCalendarUtil::_numericMonthToString($this->seed_info['mon'], false));
230  $this->tpl->setVariable('HEADER_DAY', ilCalendarUtil::_numericDayToString($this->seed_info['wday'], true));
231  $this->tpl->setVariable('HCOLSPAN', $colspan - 1);
232 
233  $this->tpl->setVariable('TXT_TIME', $lng->txt("time"));
234 
235  // show fullday events
236  foreach ($daily_apps as $event) {
237  if ($event['fullday']) {
238  $this->showFulldayAppointment($event);
239  }
240  }
241  $this->tpl->setCurrentBlock('fullday_apps');
242  $this->tpl->setVariable('TXT_F_DAY', $lng->txt("cal_all_day"));
243  $this->tpl->setVariable('COLSPAN', $colspan - 1);
244  $this->tpl->parseCurrentBlock();
245 
246  // parse the hour rows
247  foreach ($hours as $numeric => $hour) {
248  if (!($numeric % 60) || ($numeric == $morning_aggr && $morning_aggr) ||
249  ($numeric == $evening_aggr && $evening_aggr)) {
250  if (!$no_add) {
251  $this->tpl->setCurrentBlock("new_app2");
252  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
253  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
254  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
255  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'hour', floor($numeric / 60));
256  $this->tpl->setVariable('NEW_APP_GLYPH', $renderer->render(
257  $ui_factory->glyph()->add(
258  $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'add')
259  )
260  ));
261  $this->tpl->parseCurrentBlock();
262  }
263 
264  // aggregation rows
265  if (($numeric == $morning_aggr && $morning_aggr) ||
266  ($numeric == $evening_aggr && $evening_aggr)) {
267  $this->tpl->setVariable('TIME_ROWSPAN', 1);
268  }
269  // rastered hour
270  else {
271  $this->tpl->setVariable('TIME_ROWSPAN', 60 / $raster);
272  }
273 
274  $this->tpl->setCurrentBlock('time_txt');
275 
276  $this->tpl->setVariable('TIME', $hour['txt']);
277  $this->tpl->parseCurrentBlock();
278  }
279 
280  foreach ($hour['apps_start'] as $app) {
281  $this->showAppointment($app);
282  }
283 
284  if ($ilUser->prefs["screen_reader_optimization"]) {
285  // see #0022492
286  //$this->tpl->touchBlock('scrd_app_cell');
287  }
288 
289  for ($i = ($colspan - 1);$i > $hour['apps_num'];$i--) {
290  $this->tpl->setCurrentBlock('empty_cell');
291  $this->tpl->setVariable('EMPTY_WIDTH', (100 / (int) ($colspan - 1)) . '%');
292 
293  // last "slot" of hour needs border
294  if ($numeric % 60 == 60 - $raster ||
295  ($numeric == $morning_aggr && $morning_aggr) ||
296  ($numeric == $evening_aggr && $evening_aggr)) {
297  $this->tpl->setVariable('EMPTY_STYLE', ' calempty_border');
298  }
299 
300  $this->tpl->parseCurrentBlock();
301  }
302 
303  $this->tpl->touchBlock('time_row');
304  }
305  }
306 
314  protected function showFulldayAppointment($a_app)
315  {
318 
319  $event_tpl = new ilTemplate('tpl.day_event_view.html', true, true, 'Services/Calendar');
320 
321  // milestone icon
322  if ($a_app['event']->isMilestone()) {
323  $event_tpl->setCurrentBlock('fullday_ms_icon');
324  $event_tpl->setVariable('ALT_FD_MS', $this->lng->txt("cal_milestone"));
325  $event_tpl->setVariable('SRC_FD_MS', ilUtil::getImagePath("icon_ms.svg"));
326  $event_tpl->parseCurrentBlock();
327  }
328 
329  $event_tpl->setCurrentBlock('fullday_app');
330 
331  $compl = ($a_app['event']->isMilestone() && $a_app['event']->getCompletion() > 0)
332  ? " (" . $a_app['event']->getCompletion() . "%)"
333  : "";
334 
335  $shy = $this->getAppointmentShyButton($a_app['event'], $a_app['dstart'], "");
336 
337  //$title = ($new_title = $this->getContentByPlugins($a_app['event'], $a_app['dstart'], $shy))? $new_title : $shy;
338 
339  $content = $shy . $compl;
340 
341  $event_tpl->setVariable('EVENT_CONTENT', $content);
342 
343  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
344  $event_tpl->setVariable('F_APP_BGCOLOR', $color);
345  $event_tpl->setVariable('F_APP_FONTCOLOR', ilCalendarUtil::calculateFontColor($color));
346 
347  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
348  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
349  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'app_id', $a_app['event']->getEntryId());
350  $event_tpl->setVariable('F_APP_EDIT_LINK', $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'edit'));
351 
352  if ($event_html_by_plugin = $this->getContentByPlugins($a_app['event'], $a_app['dstart'], $content, $event_tpl)) {
353  $body_html = $event_html_by_plugin;
354  } else {
355  $event_tpl->parseCurrentBlock();
356  $body_html = $event_tpl->get();
357  }
358 
359  $this->tpl->setCurrentBlock("content_fd");
360  $this->tpl->setVariable("CONTENT_EVENT", $body_html);
361  $this->tpl->parseCurrentBlock();
362 
363  $this->num_appointments++;
364  }
365 
372  protected function showAppointment($a_app)
373  {
375 
376  $event_tpl = new ilTemplate('tpl.day_event_view.html', true, true, 'Services/Calendar');
377 
378  if (!$ilUser->prefs["screen_reader_optimization"]) {
379  $event_tpl->setCurrentBlock('app');
380  } else {
381  $event_tpl->setCurrentBlock('scrd_app');
382  }
383 
384  $this->tpl->setVariable('APP_ROWSPAN', $a_app['rowspan']);
385  //$event_tpl->setVariable('APP_TITLE',$a_app['event']->getPresentationTitle(false));
386 
387  switch ($this->user_settings->getTimeFormat()) {
389  $time = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE, 'H:i', $this->timezone);
390  break;
391 
393  $time = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE, 'h:ia', $this->timezone);
394  break;
395  }
396 
397  // add end time for screen readers
398  if ($ilUser->prefs["screen_reader_optimization"]) {
399  switch ($this->user_settings->getTimeFormat()) {
401  $time .= "-" . $a_app['event']->getEnd()->get(IL_CAL_FKT_DATE, 'H:i', $this->timezone);
402  break;
403 
405  $time .= "-" . $a_app['event']->getEnd()->get(IL_CAL_FKT_DATE, 'h:ia', $this->timezone);
406  break;
407  }
408  }
409 
410  $shy = $this->getAppointmentShyButton($a_app['event'], $a_app['dstart'], "");
411 
412  $title = $shy;
413  $content = ($time != "")? $time . " " . $title : $title;
414 
415  $event_tpl->setVariable('EVENT_CONTENT', $content);
416 
417  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
418  $event_tpl->setVariable('APP_BGCOLOR', $color);
419  //$this->tpl->setVariable('APP_BGCOLOR',$color);
420  $event_tpl->setVariable('APP_COLOR', ilCalendarUtil::calculateFontColor($color));
421  //$this->tpl->setVariable('APP_COLOR',ilCalendarUtil::calculateFontColor($color));
422  $event_tpl->setVariable('APP_ADD_STYLES', $a_app['event']->getPresentationStyle());
423  //$this->tpl->setVariable('APP_ADD_STYLES',$a_app['event']->getPresentationStyle());
424 
425  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
426  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'seed', $this->seed->get(IL_CAL_DATE));
427  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'app_id', $a_app['event']->getEntryId());
428  $event_tpl->setVariable('APP_EDIT_LINK', $this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui', 'edit'));
429 
430  if ($event_html_by_plugin = $this->getContentByPlugins($a_app['event'], $a_app['dstart'], $content, $event_tpl)) {
431  $event_html = $event_html_by_plugin;
432  } else {
433  $event_tpl->parseCurrentBlock();
434  $event_html = $event_tpl->get();
435  }
436 
437  $this->tpl->setCurrentBlock("event_nfd");
438  $this->tpl->setVariable("CONTENT_EVENT_NFD", $event_html);
439  $this->tpl->parseCurrentBlock();
440 
441  $this->num_appointments++;
442  }
443 
450  protected function parseInfoIntoRaster($daily_apps, $morning_aggr, $evening_aggr, $raster)
451  {
453 
454  $hours = array();
455  for ($i = $morning_aggr;$i <= $evening_aggr;$i += $raster) {
456  $hours[$i]['apps_start'] = array();
457  $hours[$i]['apps_num'] = 0;
458 
459  switch ($this->user_settings->getTimeFormat()) {
461  if ($morning_aggr > 0 && $i == $morning_aggr) {
462  $hours[$i]['txt'] = sprintf('%02d:00', 0) . ' - ' .
463  sprintf('%02d:00', ceil(($i + 1) / 60));
464  } else {
465  $hours[$i]['txt'] .= sprintf('%02d:%02d', floor($i / 60), $i % 60);
466  }
467  if ($evening_aggr < 23 * 60 && $i == $evening_aggr) {
468  $hours[$i]['txt'] .= ' - ' . sprintf('%02d:00', 0);
469  }
470  break;
471 
473 
474  $this->logger->notice('Morning: ' . $morning_aggr . ' and $i:' . $i);
475 
476  if ($morning_aggr > 0 && $i == $morning_aggr) {
477  $hours[$i]['txt'] =
478  date('h a', mktime(0, 0, 0, 1, 1, 2000)) . ' - ' .
479  date('h a', mktime($this->user_settings->getDayStart(), 0, 0, 1, 1, 2000));
480  } else {
481  $hours[$i]['txt'] = date('h a', mktime(floor($i / 60), $i % 60, 0, 1, 1, 2000));
482  }
483  if ($evening_aggr < 23 * 60 && $i == $evening_aggr) {
484  $hours[$i]['txt'] .= ' - ' . date('h a', mktime(0, 0, 0, 1, 1, 2000));
485  }
486  break;
487  }
488  }
489 
490 
491  foreach ($daily_apps as $app) {
492  // fullday appointment are not relavant
493  if ($app['fullday']) {
494  continue;
495  }
496  // start hour for this day
497  #21132 #21636
498  if ($app['start_info']['mday'] != $this->seed_info['mday']) {
499  $start = 0;
500  } else {
501  $start = $app['start_info']['hours'] * 60 + $app['start_info']['minutes'];
502  }
503  #21636
504  //$start = $app['start_info']['hours']*60+$app['start_info']['minutes'];
505 
506  // end hour for this day
507  #21132
508  if ($app['end_info']['mday'] != $this->seed_info['mday']) {
509  $end = 23 * 60;
510  } elseif ($app['start_info']['hours'] == $app['end_info']['hours']) {
511  $end = $start + $raster;
512  } else {
513  $end = $app['end_info']['hours'] * 60 + $app['end_info']['minutes'];
514  }
515  //$end = $app['end_info']['hours']*60+$app['end_info']['minutes'];
516 
517  // set end to next hour for screen readers
518  if ($ilUser->prefs["screen_reader_optimization"]) {
519  $end = $start + $raster;
520  }
521 
522  if ($start < $morning_aggr) {
523  $start = $morning_aggr;
524  }
525  if ($end <= $morning_aggr) {
526  $end = $morning_aggr + $raster;
527  }
528  if ($start > $evening_aggr) {
529  $start = $evening_aggr;
530  }
531  if ($end > $evening_aggr + $raster) {
532  $end = $evening_aggr + $raster;
533  }
534  if ($end <= $start) {
535  $end = $start + $raster;
536  }
537 
538  // map start and end to raster
539  $start = floor($start / $raster) * $raster;
540  $end = ceil($end / $raster) * $raster;
541 
542  $first = true;
543  for ($i = $start;$i < $end;$i += $raster) {
544  if ($first) {
545  if (!$ilUser->prefs["screen_reader_optimization"]) {
546  $app['rowspan'] = ceil(($end - $start) / $raster);
547  } else { // screen readers get always a rowspan of 1
548  $app['rowspan'] = 1;
549  }
550  $hours[$i]['apps_start'][] = $app;
551  $first = false;
552  }
553  $hours[$i]['apps_num']++;
554  }
555  }
556 
557  return $hours;
558  }
559 
567  protected function calculateColspan($hours)
568  {
570 
571 
572  $colspan = 1;
573  foreach ($hours as $hour) {
574  $colspan = max($colspan, $hour['apps_num'] + 1);
575  }
576 
577  // screen reader: always two cols (time and event col)
578  if ($ilUser->prefs["screen_reader_optimization"]) {
579  $colspan = 2;
580  }
581 
582  return max($colspan, 2);
583  }
584 }
static _getInstance()
get singleton instance
getAppointmentShyButton($a_calendar_entry, $a_dstart, $a_title_forced="")
$_SESSION["AccountId"]
static _numericDayToString($a_day, $a_long=true)
get
global $DIC
Definition: saml.php:7
$_GET["client_id"]
executeCommand()
Execute command.
static _getInstanceByUserId($a_user_id)
get singleton instance
static _getInstance(ilDate $seed, $a_app)
get singleton instance
getCurrentApp()
Get app for id.
const IL_CAL_UNIX
showAppointment($a_app)
show appointment
user()
Definition: user.php:4
__construct(ilDate $seed_date)
Constructor.
static _numericMonthToString($a_month, $a_long=true)
numeric month to string
parseInfoIntoRaster($daily_apps, $morning_aggr, $evening_aggr, $raster)
calculate overlapping hours
global $ilCtrl
Definition: ilias.php:18
$start
Definition: bench.php:8
$time
Definition: cron.php:21
$r
Definition: example_031.php:79
calculateColspan($hours)
calculate colspan
Class for single dates.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
special template class to simplify handling of ITX/PEAR
const IL_CAL_FKT_DATE
$ilUser
Definition: imgupload.php:18
static calculateFontColor($a_html_color_code)
Calculate best font color from html hex color code.
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
Administrate calendar appointments.
static initDragDrop()
Init YUI Drag and Drop.
showFulldayAppointment($a_app)
show fullday appointment
$i
Definition: disco.tpl.php:19
getContentByPlugins($a_cal_entry, $a_start_date, $a_content, $a_tpl)
Presentation day view.
Represents a list of calendar appointments (including recurring events) for a specific user in a give...