Add lots of JS magic to make calendar usable
[infodrom.org/service.infodrom.org] / class / calendar.class.php
index 68ca9b8..8fc45ca 100644 (file)
@@ -6,7 +6,7 @@ class Calendar extends DatabaseTable {
   {
     $db = new Database(DBDRIVER, DBHOST, DAV_DBNAME, DBUSER, DBPASS);
 
-    parent::__construct('calendar_item', $id, $db, 'dav_id');
+    parent::__construct('calendar_item', false, $db);
   }
 
   public static function pgTimestamp($timestamp)
@@ -72,4 +72,240 @@ class Calendar extends DatabaseTable {
     return $this->db->fetchObjectList($sql);
   }
 
+  public function ajaxMonths(Array $data)
+  {
+    $monthname = array('','Jan','Feb','Mär', 'Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez');
+    $sql = sprintf("SELECT DISTINCT extract(year from dtstart) AS year,extract(month from dtstart) AS month " .
+                  "FROM calendar_item WHERE user_no = %d ORDER BY year DESC,month DESC",
+                  DAV_USER_NO);
+    $out = '';
+    $now = array(date('Y'), date('m'));
+    foreach ($this->db->fetchObjectList($sql) as $row) {
+      $out .= sprintf('<option value="%04d-%02d"%s>%s %04d</option>',
+                     $row->year, $row->month,
+                     $row->year == $now[0] && $row->month == $now[1] ? ' selected' : '',
+                     utf8_encode($monthname[$row->month]), $row->year);
+    }
+
+    return array('values' => array('thismonth' => date('Y-m')),
+                'html' => array('month' => $out));
+  }
+
+  private function getMonthData($year, $month)
+  {
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    $areaDates = array();
+    for ($i=1; $i < 8; $i++) {
+      $date = sprintf('%04d-%02d-%02d', $year, $month, 1);
+      $sql = sprintf("SELECT dav_id FROM calendar_item WHERE user_no = %d AND dtstart::date = '%s'::date - INTERVAL '%d DAY' ORDER BY dtstart",
+                    DAV_USER_NO, $date, $i);
+      foreach ($this->fetchObjectList($sql) as $row) {
+        $item = new Calendar_Item($row->dav_id);
+       if ($item->isRegular()) continue;
+
+       foreach ($item->getDays() as $adate) {
+         if (!array_key_exists($adate, $areaDates))
+           $areaDates[$adate] = array();
+         $areaDates[$adate][] = $item;
+       }
+      }
+    }
+
+    $regDates = array();
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (0, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      $sql = sprintf("SELECT dav_id FROM calendar_item WHERE user_no = %d AND dtstart::date = '%s'::date ORDER BY dtstart",
+                    DAV_USER_NO, $date);
+
+      foreach ($this->fetchObjectList($sql) as $row) {
+       $item = new Calendar_Item($row->dav_id);
+
+       if (!$item->isRegular()) {
+         foreach ($item->getDays() as $adate) {
+           if (!array_key_exists($adate, $areaDates))
+             $areaDates[$adate] = array();
+           $areaDates[$adate][] = $item;
+         }
+       } else {
+         if (!array_key_exists($date, $regDates))
+           $regDates[$date] = array();
+         $regDates[$date][] = $item;
+       }
+      }
+    }
+
+    return array($areaDates, $regDates);
+  }
+
+  private function formatOneMonth($year, $month)
+  {
+    $weekday = array('', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
+    $monthname = array('','Jan','Feb','Mär', 'Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez');
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    $out = sprintf('<div class="head" month="%04d-%02d">%s %04d</div>',
+                  $year, $month, $monthname[intval($month)], $year);
+
+    list($areaDates, $regDates) = $this->getMonthData($year, $month);
+
+    $today = date('Y-m-d');
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (0, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      $items = array();
+
+      if (array_key_exists($date, $areaDates))
+       foreach ($areaDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      if (array_key_exists($date, $regDates))
+       foreach ($regDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      $class = date('N', $timestamp) == 7 ? 'sunday' : 'day';
+      if ($today == $date) $class .= ' today';
+      $kw = date('N', $timestamp) == 1 ? sprintf('<div class="kw">%d</div>', date('W', $timestamp)) : '';
+      $out .= sprintf('<div class="%s" day="%d"><div class="wday">%s</div><div class="date">%d.</div>%s%s</div>',
+                     $class,
+                     $day,
+                     $weekday[intval(date('N', $timestamp))],
+                     $day,
+                     count($items) ? implode('', $items) : '&nbsp;',
+                     $kw);
+    }
+    return $out;
+  }
+
+  public function ajaxBiMonth(Array $data)
+  {
+    list($year, $month) = explode('-', $data['month']);
+    if (!empty($data['direction'])) {
+      switch ($data['direction']) {
+      case 'prev':
+       if ($month > 1) $month--;
+       else {$year--; $month = 12;}
+       break;
+      case 'next':
+       if ($month < 12) $month++;
+       else {$year++; $month = 1;}
+       break;
+      }
+    }
+
+    $monthStr = sprintf('%04d-%02d', $year, $month);
+    $right = $this->formatOneMonth($year, $month);
+
+    if ($month < 12) $month++;
+    else {$year++; $month = 1;}
+    $left = $this->formatOneMonth($year, $month);
+
+    $out = '<div class="bimonth">';
+
+    $out .= '<div class="monthcolumn">';
+    $out .= $right;
+    $out .= '</div>';
+
+    $out .= '<div class="monthcolumn">';
+    $out .= $left;
+    $out .= '</div>';
+
+    $out .= '</div>';
+
+    return array('values' => array('thismonth' => $monthStr),
+                'html' => array('termine' => $out));
+  }
+
+  public function ajaxMonth(Array $data)
+  {
+    $monthname = array('','Januar','Februar','März', 'April','Mai','Juni','Juli','August','September','Oktober','November','Dezember');
+
+    list($year, $month) = explode('-', $data['month']);
+    if (!empty($data['direction'])) {
+      switch ($data['direction']) {
+      case 'prev':
+       if ($month > 1) $month--;
+       else {$year--; $month = 12;}
+       break;
+      case 'next':
+       if ($month < 12) $month++;
+       else {$year++; $month = 1;}
+       break;
+      }
+    }
+
+    $monthStr = sprintf('%04d-%02d', $year, $month);
+    $monthText = utf8_encode($monthname[intval($month)] . ' ' . $year);
+    $numdays = cal_days_in_month(CAL_GREGORIAN, $month, $year);
+
+    list($areaDates, $regDates) = $this->getMonthData($year, $month);
+
+    $out = '<div class="month">';
+
+    $out .= <<<EOT
+<table width="100%" cellspacing="0" border="collapse">
+<thead>
+<tr><td colspan="8" class="title">{$monthText}</td></tr>
+<tr>
+      <td width="2%">&nbsp;</td>
+      <td width="14%">Montag</td>
+      <td width="14%">Dienstag</td>
+      <td width="14%">Mittwoch</td>
+      <td width="14%">Donnerstag</td>
+      <td width="14%">Freitag</td>
+      <td width="14%">Samstag</td>
+      <td width="14%">Sonntag</td>
+</tr>
+</thead>
+<tbody>
+EOT;
+
+    $timestamp = mktime (4, 0, 0, $month, 1, $year);
+    if (date('N', $timestamp) != 1) {
+      $out .= '<tr>';
+      $out .= sprintf('<td width="2%%">%d</td>', date('W', $timestamp));
+      for ($i=1; $i < date('N', $timestamp); $i++)
+       $out .= '<td width="14%" class="empty">&nbsp;</td>';
+    }
+
+    $today = date('Y-m-d');
+    for ($day=1; $day <= $numdays; $day++) {
+      $timestamp = mktime (4, 0, 0, $month, $day, $year);
+      $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
+      if (date('N', $timestamp) == 1)
+       $out .= sprintf('<tr><td width="2%%">%d</td>', date('W', $timestamp));
+
+      $items = array();
+
+      if (array_key_exists($date, $areaDates))
+       foreach ($areaDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      if (array_key_exists($date, $regDates))
+       foreach ($regDates[$date] as $item)
+         $items[] = $item->toSpan();
+
+      $out .= sprintf('<td width="14%%"><div class="day">%d</day><div>%s</div></td>',
+                     date('d', $timestamp),
+                     count($items) ? implode('<br />', $items) : '&nbsp;');
+
+      if (date('N', $timestamp) == 7)
+       $out .= '</tr>';
+    }
+
+    if (date('N', $timestamp) != 7) {
+      for ($i=date('N', $timestamp); $i < 7; $i++)
+        $out .= '<td width="14%" class="empty">&nbsp;</td>';
+      $out .= '</tr>';
+    }
+
+    $out .= '</tbody></table>';
+
+    $out .= '</div>';
+
+    return array('values' => array('thismonth' => $monthStr),
+                'html' => array('termine' => $out));
+  }
+
 }