ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCalendarDayGUI.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2008 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
33 include_once('./Services/Calendar/classes/class.ilDate.php');
34 include_once('./Services/Calendar/classes/class.ilCalendarUtil.php');
35 include_once('./Services/Calendar/classes/class.ilCalendarHeaderNavigationGUI.php');
36 include_once('./Services/Calendar/classes/class.ilCalendarUserSettings.php');
37 include_once('./Services/Calendar/classes/class.ilCalendarAppointmentColors.php');
38 
39 
41 {
42  protected $seed = null;
43  protected $seed_info = array();
44  protected $user_settings = null;
45 
46  protected $lng;
47  protected $ctrl;
48  protected $tabs_gui;
49  protected $tpl;
50 
51  protected $num_appointments = 1;
52 
53  protected $timezone = 'UTC';
54 
62  public function __construct(ilDate $seed_date)
63  {
64  global $ilCtrl, $lng, $ilUser,$ilTabs,$tpl;
65 
66  $this->seed = $seed_date;
67  $this->seed_info = $this->seed->get(IL_CAL_FKT_GETDATE);
68 
69  $this->tpl = $tpl;
70  $this->lng = $lng;
71  $this->ctrl = $ilCtrl;
72  $this->tabs_gui = $ilTabs;
73 
74  $this->user_settings = ilCalendarUserSettings::_getInstanceByUserId($ilUser->getId());
75  $this->app_colors = new ilCalendarAppointmentColors($ilUser->getId());
76 
77  $this->timezone = $ilUser->getTimeZone();
78  }
79 
86  public function executeCommand()
87  {
88  global $ilCtrl,$tpl;
89 
90  $next_class = $ilCtrl->getNextClass();
91  switch($next_class)
92  {
93  case 'ilcalendarappointmentgui':
94  $this->ctrl->setReturn($this,'');
95  $this->tabs_gui->setSubTabActive($_SESSION['cal_last_tab']);
96 
97  // initial date for new calendar appointments
98  $idate = new ilDate($_REQUEST['idate'], IL_CAL_DATE);
99 
100  include_once('./Services/Calendar/classes/class.ilCalendarAppointmentGUI.php');
101  $app = new ilCalendarAppointmentGUI($this->seed,$idate,(int) $_GET['app_id']);
102  $this->ctrl->forwardCommand($app);
103  break;
104 
105  default:
106  $cmd = $this->ctrl->getCmd("show");
107  $this->$cmd();
108  $tpl->setContent($this->tpl->get());
109  break;
110  }
111  return true;
112  }
113 
120  protected function show()
121  {
122  global $lng, $ilUser;
123 
124  // config
125  $raster = 15;
126  if($this->user_settings->getDayStart())
127  {
128  // push starting point to last "slot" of hour BEFORE morning aggregation
129  $morning_aggr = ($this->user_settings->getDayStart()-1)*60+(60-$raster);
130  }
131  else
132  {
133  $morning_aggr = 0;
134  }
135  $evening_aggr = $this->user_settings->getDayEnd()*60;
136 
137 
138  $this->tpl = new ilTemplate('tpl.day_view.html',true,true,'Services/Calendar');
139 
140  include_once('./Services/YUI/classes/class.ilYuiUtil.php');
143 
144  if(isset($_GET["bkid"]))
145  {
146  $user_id = $_GET["bkid"];
147  $no_add = true;
148  }
149  elseif($ilUser->getId() == ANONYMOUS_USER_ID)
150  {
151  $user_id = $ilUser->getId();
152  $no_add = true;
153  }
154  else
155  {
156  $user_id = $ilUser->getId();
157  $no_add = false;
158  }
159  include_once('Services/Calendar/classes/class.ilCalendarSchedule.php');
160  $this->scheduler = new ilCalendarSchedule($this->seed,ilCalendarSchedule::TYPE_DAY,$user_id);
161  $this->scheduler->addSubitemCalendars(true);
162  $this->scheduler->calculate();
163  $daily_apps = $this->scheduler->getByDay($this->seed,$this->timezone);
164  $hours = $this->parseInfoIntoRaster($daily_apps,
165  $morning_aggr,
166  $evening_aggr,
167  $raster
168  );
169 
170  $colspan = $this->calculateColspan($hours);
171 
172  $navigation = new ilCalendarHeaderNavigationGUI($this,$this->seed,ilDateTime::DAY);
173  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
174 
175  // add milestone link
176  include_once('Services/Calendar/classes/class.ilCalendarSettings.php');
177  $settings = ilCalendarSettings::_getInstance();
178 
179  if(!$no_add)
180  {
181  if ($settings->getEnableGroupMilestones())
182  {
183  $this->tpl->setCurrentBlock("new_ms");
184  $this->tpl->setVariable('H_NEW_MS_SRC',ilUtil::getImagePath('ms_add.png'));
185  $this->tpl->setVariable('H_NEW_MS_ALT',$this->lng->txt('cal_new_ms'));
186  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
187  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
188  $this->tpl->setVariable('NEW_MS_LINK',$this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui','addMilestone'));
189  $this->tpl->parseCurrentBlock();
190  }
191 
192  $this->tpl->setCurrentBlock("new_app1");
193  $this->tpl->setVariable('H_NEW_APP_SRC',ilUtil::getImagePath('date_add.png'));
194  $this->tpl->setVariable('H_NEW_APP_ALT',$this->lng->txt('cal_new_app'));
195  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
196  $this->ctrl->setParameterByClass('ilcalendarappointmentgui', 'idate', $this->seed->get(IL_CAL_DATE));
197  $this->tpl->setVariable('NEW_APP_LINK',$this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui','add'));
198  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
199  $this->tpl->parseCurrentBlock();
200  }
201 
202  $this->tpl->setVariable('NAVIGATION',$navigation->getHTML());
203 
204  $this->tpl->setVariable('HEADER_DATE',$this->seed_info['mday'].' '.ilCalendarUtil::_numericMonthToString($this->seed_info['mon'],false));
205  $this->tpl->setVariable('HEADER_DAY',ilCalendarUtil::_numericDayToString($this->seed_info['wday'],true));
206  $this->tpl->setVariable('HCOLSPAN',$colspan - 1);
207 
208  $this->tpl->setVariable('TXT_TIME', $lng->txt("time"));
209 
210  // show fullday events
211  foreach($daily_apps as $event)
212  {
213  if($event['fullday'])
214  {
215  $this->showFulldayAppointment($event);
216  }
217  }
218  $this->tpl->setCurrentBlock('fullday_apps');
219  $this->tpl->setVariable('TXT_F_DAY', $lng->txt("cal_all_day"));
220  $this->tpl->setVariable('COLSPAN',$colspan - 1);
221  $this->tpl->parseCurrentBlock();
222 
223  // parse the hour rows
224  foreach($hours as $numeric => $hour)
225  {
226  if(!($numeric%60) || ($numeric == $morning_aggr && $morning_aggr) ||
227  ($numeric == $evening_aggr && $evening_aggr))
228  {
229  if(!$no_add)
230  {
231  $this->tpl->setCurrentBlock("new_app2");
232  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
233  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
234  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','idate',$this->seed->get(IL_CAL_DATE));
235  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','hour',floor($numeric/60));
236  $this->tpl->setVariable('NEW_APP_HOUR_LINK',$this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui','add'));
237  $this->tpl->setVariable('NEW_APP_SRC',ilUtil::getImagePath('date_add.png'));
238  $this->tpl->setVariable('NEW_APP_ALT',$this->lng->txt('cal_new_app'));
239  $this->tpl->parseCurrentBlock();
240  }
241 
242  // aggregation rows
243  if(($numeric == $morning_aggr && $morning_aggr) ||
244  ($numeric == $evening_aggr && $evening_aggr))
245  {
246  $this->tpl->setVariable('TIME_ROWSPAN', 1);
247  }
248  // rastered hour
249  else
250  {
251  $this->tpl->setVariable('TIME_ROWSPAN', 60/$raster);
252  }
253 
254  $this->tpl->setCurrentBlock('time_txt');
255 
256  $this->tpl->setVariable('TIME',$hour['txt']);
257  $this->tpl->parseCurrentBlock();
258  }
259 
260  foreach($hour['apps_start'] as $app)
261  {
262  $this->showAppointment($app);
263  }
264 
265  if ($ilUser->prefs["screen_reader_optimization"])
266  {
267  $this->tpl->touchBlock('scrd_app_cell');
268  }
269 
270  for($i = ($colspan - 1);$i > $hour['apps_num'];$i--)
271  {
272  $this->tpl->setCurrentBlock('empty_cell');
273  $this->tpl->setVariable('EMPTY_WIDTH',(100 / (int) ($colspan - 1)).'%');
274 
275  // last "slot" of hour needs border
276  if($numeric%60 == 60-$raster ||
277  ($numeric == $morning_aggr && $morning_aggr) ||
278  ($numeric == $evening_aggr && $evening_aggr))
279  {
280  $this->tpl->setVariable('EMPTY_STYLE', ' calempty_border');
281  }
282 
283  $this->tpl->parseCurrentBlock();
284  }
285 
286  $this->tpl->touchBlock('time_row');
287  }
288  }
289 
297  protected function showFulldayAppointment($a_app)
298  {
299  $this->tpl->setCurrentBlock('panel_code');
300  $this->tpl->setVariable('NUM',$this->num_appointments);
301  $this->tpl->parseCurrentBlock();
302 
303  // milestone icon
304  if ($a_app['event']->isMilestone())
305  {
306  $this->tpl->setCurrentBlock('fullday_ms_icon');
307  $this->tpl->setVariable('ALT_FD_MS', $this->lng->txt("cal_milestone"));
308  $this->tpl->setVariable('SRC_FD_MS', ilUtil::getImagePath("icon_ms_s.png"));
309  $this->tpl->parseCurrentBlock();
310  }
311 
312  $this->tpl->setCurrentBlock('fullday_app');
313  include_once('./Services/Calendar/classes/class.ilCalendarAppointmentPanelGUI.php');
314  $this->tpl->setVariable('PANEL_F_DAY_DATA',ilCalendarAppointmentPanelGUI::_getInstance($this->seed)->getHTML($a_app));
315  $this->tpl->setVariable('F_DAY_ID',$this->num_appointments);
316 
317  $compl = ($a_app['event']->isMilestone() && $a_app['event']->getCompletion() > 0)
318  ? " (".$a_app['event']->getCompletion()."%)"
319  : "";
320  $this->tpl->setVariable('F_APP_TITLE',$a_app['event']->getPresentationTitle(false).$compl);
321  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
322  $this->tpl->setVariable('F_APP_BGCOLOR',$color);
323  $this->tpl->setVariable('F_APP_FONTCOLOR',ilCalendarUtil::calculateFontColor($color));
324 
325  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
326  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
327  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','app_id',$a_app['event']->getEntryId());
328  $this->tpl->setVariable('F_APP_EDIT_LINK',$this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui','edit'));
329 
330  $this->tpl->parseCurrentBlock();
331 
332 
333  $this->num_appointments++;
334  }
335 
342  protected function showAppointment($a_app)
343  {
344  global $ilUser;
345 
346  $this->tpl->setCurrentBlock('panel_code');
347  $this->tpl->setVariable('NUM',$this->num_appointments);
348  $this->tpl->parseCurrentBlock();
349 
350  if (!$ilUser->prefs["screen_reader_optimization"])
351  {
352  $this->tpl->setCurrentBlock('app');
353  }
354  else
355  {
356  $this->tpl->setCurrentBlock('scrd_app');
357  }
358 
359  include_once('./Services/Calendar/classes/class.ilCalendarAppointmentPanelGUI.php');
360  $this->tpl->setVariable('PANEL_DATA',ilCalendarAppointmentPanelGUI::_getInstance($this->seed)->getHTML($a_app));
361  $this->tpl->setVariable('PANEL_NUM',$this->num_appointments);
362 
363  $this->tpl->setVariable('APP_ROWSPAN',$a_app['rowspan']);
364  $this->tpl->setVariable('APP_TITLE',$a_app['event']->getPresentationTitle(false));
365 
366  switch($this->user_settings->getTimeFormat())
367  {
369  $title = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE,'H:i',$this->timezone);
370  break;
371 
373  $title = $a_app['event']->getStart()->get(IL_CAL_FKT_DATE,'h:ia',$this->timezone);
374  break;
375  }
376 
377  // add end time for screen readers
378  if ($ilUser->prefs["screen_reader_optimization"])
379  {
380  switch($this->user_settings->getTimeFormat())
381  {
383  $title.= "-".$a_app['event']->getEnd()->get(IL_CAL_FKT_DATE,'H:i',$this->timezone);
384  break;
385 
387  $title.= "-".$a_app['event']->getEnd()->get(IL_CAL_FKT_DATE,'h:ia',$this->timezone);
388  break;
389  }
390  }
391 
392 
393  // booking
394  if($a_app['category_type'] == ilCalendarCategory::TYPE_CH)
395  {
396  include_once 'Services/Booking/classes/class.ilBookingEntry.php';
397  $entry = new ilBookingEntry($a_app['event']->getContextId());
398  if($entry)
399  {
400  $title .= ' '.$a_app['event']->getTitle();
401  if($entry->isOwner())
402  {
403  $max = (int)$entry->getNumberOfBookings();
404  $current = (int)$entry->getCurrentNumberOfBookings($a_app['event']->getEntryId());
405  if($max > 1)
406  {
407  $title .= ' ('.$current.'/'.$max.')';
408  }
409  else if($current == $max)
410  {
411  $title .= ' ('.$this->lng->txt('cal_booked_out').')';
412  }
413  else
414  {
415  $title .= ' ('.$this->lng->txt('cal_book_free').')';
416  }
417  }
418  else if($entry->hasBooked($a_app['event']->getEntryId()))
419  {
420  $title .= ' ('.$this->lng->txt('cal_date_booked').')';
421  }
422  }
423  }
424  else
425  {
426  $title .= (' '.$a_app['event']->getPresentationTitle(false));
427  }
428 
429  $this->tpl->setVariable('APP_TITLE',$title);
430 
431  $color = $this->app_colors->getColorByAppointment($a_app['event']->getEntryId());
432  $this->tpl->setVariable('APP_BGCOLOR',$color);
433  $this->tpl->setVariable('APP_COLOR',ilCalendarUtil::calculateFontColor($color));
434 
435  $this->ctrl->clearParametersByClass('ilcalendarappointmentgui');
436  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','seed',$this->seed->get(IL_CAL_DATE));
437  $this->ctrl->setParameterByClass('ilcalendarappointmentgui','app_id',$a_app['event']->getEntryId());
438  $this->tpl->setVariable('APP_EDIT_LINK',$this->ctrl->getLinkTargetByClass('ilcalendarappointmentgui','edit'));
439 
440  $this->tpl->parseCurrentBlock();
441 
442  $this->num_appointments++;
443  }
444 
451  protected function parseInfoIntoRaster($daily_apps, $morning_aggr, $evening_aggr, $raster)
452  {
453  $hours = array();
454  for($i = $morning_aggr;$i <= $evening_aggr;$i+=$raster)
455  {
456  $hours[$i]['apps_start'] = array();
457  $hours[$i]['apps_num'] = 0;
458 
459  switch($this->user_settings->getTimeFormat())
460  {
462  if ($morning_aggr > 0 && $i == $morning_aggr)
463  {
464  $hours[$i]['txt'] = sprintf('%02d:00',0)."-".
465  sprintf('%02d:00',ceil(($i+1)/60));
466  }
467  else
468  {
469  $hours[$i]['txt'].= sprintf('%02d:%02d',floor($i/60),$i%60);
470  }
471  if ($evening_aggr < 23*60 && $i == $evening_aggr)
472  {
473  $hours[$i]['txt'].= "-".sprintf('%02d:00',23);
474  }
475  break;
476 
478  if ($morning_aggr > 0 && $i == $morning_aggr)
479  {
480  $hours[$i]['txt'] = date('h a',mktime(0,0,0,1,1,2000))."-";
481  }
482  $hours[$i]['txt'] = date('h a',mktime(floor($i/60),$i%60,0,1,1,2000));
483  if ($evening_aggr < 23*60 && $i == $evening_aggr)
484  {
485  $hours[$i]['txt'].= "-".date('h a',mktime(23,0,0,1,1,2000));
486  }
487  break;
488  }
489  }
490 
491 
492  foreach($daily_apps as $app)
493  {
494  global $ilUser;
495 
496  // fullday appointment are not relavant
497  if($app['fullday'])
498  {
499  continue;
500  }
501  // start hour for this day
502  if($app['start_info']['mday'] != $this->seed_info['mday'])
503  {
504  $start = 0;
505  }
506  else
507  {
508  $start = $app['start_info']['hours']*60+$app['start_info']['minutes'];
509  }
510  // end hour for this day
511  if($app['end_info']['mday'] != $this->seed_info['mday'])
512  {
513  $end = 23*60;
514  }
515  elseif($app['start_info']['hours'] == $app['end_info']['hours'])
516  {
517  $end = $start+$raster;
518  }
519  else
520  {
521  $end = $app['end_info']['hours']*60+$app['end_info']['minutes'];
522  }
523 
524  // set end to next hour for screen readers
525  if ($ilUser->prefs["screen_reader_optimization"])
526  {
527  $end = $start+$raster;
528  }
529 
530  if ($start < $morning_aggr)
531  {
532  $start = $morning_aggr;
533  }
534  if ($end <= $morning_aggr)
535  {
536  $end = $morning_aggr+$raster;
537  }
538  if ($start > $evening_aggr)
539  {
540  $start = $evening_aggr;
541  }
542  if ($end > $evening_aggr+$raster)
543  {
544  $end = $evening_aggr+$raster;
545  }
546  if ($end <= $start)
547  {
548  $end = $start+$raster;
549  }
550 
551  // map start and end to raster
552  $start = floor($start/$raster)*$raster;
553  $end = ceil($end/$raster)*$raster;
554 
555  $first = true;
556  for($i = $start;$i < $end;$i+=$raster)
557  {
558  if($first)
559  {
560  if (!$ilUser->prefs["screen_reader_optimization"])
561  {
562  $app['rowspan'] = ceil(($end - $start)/$raster);
563  }
564  else // screen readers get always a rowspan of 1
565  {
566  $app['rowspan'] = 1;
567  }
568  $hours[$i]['apps_start'][] = $app;
569  $first = false;
570  }
571  $hours[$i]['apps_num']++;
572  }
573  }
574 
575  return $hours;
576  }
577 
585  protected function calculateColspan($hours)
586  {
587  global $ilUser;
588 
589  $colspan = 1;
590  foreach($hours as $hour)
591  {
592  $colspan = max($colspan,$hour['apps_num'] + 1);
593  }
594 
595  // screen reader: always two cols (time and event col)
596  if ($ilUser->prefs["screen_reader_optimization"])
597  {
598  $colspan = 2;
599  }
600 
601  return max($colspan,2);
602  }
603 
604 }
605 ?>