rcmail = $rcmail; $this->type = $type; $url = $this->rcmail->config->get('caldav_url', false); if(!$url) return; if ($rcmail->config->get('timezone') === "auto") { $tz = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : date('Z')/3600; } else { $tz = $rcmail->config->get('timezone'); if($rcmail->config->get('dst_active')) { $tz++; } } $this->usertimezone = $tz; $user = $this->rcmail->config->get('caldav_user','demo'); $pass = $this->rcmail->config->get('caldav_password',$this->rcmail->encrypt('pass')); $auth = $this->rcmail->config->get('caldav_auth','basic'); $extr = $this->rcmail->config->get('caldav_extr','1'); $account = array( 'user' => $user, 'pass' => $pass, 'url' => $url, 'auth' => $auth, 'extr' => $extr, ); $this->account = $account; $this->connect($account['url'], $account['user'], $account['pass'], $account['auth']); $public_caldavs = $rcmail->config->get('public_caldavs', array()); foreach($public_caldavs as $category => $caldav){ $public_caldavs[$category]['pass'] = $rcmail->encrypt($caldav['pass']); } $caldavs = array_merge($rcmail->config->get('caldavs', array()), $public_caldavs); $this->caldavs = $caldavs; } private function connect($url, $user, $pass, $auth = 'basic'){ if($this->type == 'caldav'){ $rcmail = $this->rcmail; $googleuser = $rcmail->config->get('googleuser', false); $googlepass= $rcmail->config->get('googlepass', false); if($user == '%gu'){ if($googleuser){ $user = str_replace('%gu', $googleuser, $user); } } else if($user == '%u'){ $user = str_replace('%u', $_SESSION['username'], $user); } $pass_clear = false; if($pass == '%gp'){ if($googlepass){ $pass = str_replace('%gp', $rcmail->decrypt($googlepass), $pass); $pass_clear = true; } } else if($pass == '%p'){ $pass = str_replace('%p', $rcmail->decrypt($_SESSION['password']), $pass); $pass_clear = true; } if(!$pass_clear){ $pass = $this->rcmail->decrypt($pass); if($pass == '%gp'){ if($googlepass){ $pass = str_replace('%gp', $rcmail->decrypt($googlepass), $pass); } } else if($pass == '%p'){ $pass = str_replace('%p', $rcmail->decrypt($_SESSION['password']), $pass); } } if(strpos($url,'%gu')) $url = str_replace('%gu', $googleuser, $url); if(strpos($url,'%u')) $url = str_replace('%u', $_SESSION['username'], $url); $url = slashify($url); if($url == "/"){ $url = 'https://www.google.com/calendar/dav/john.doe@gmail.com/events/'; } if(!$auth) $auth = 'basic'; if($user != '%u' && $user != '%gu' && $pass !='%p' && $pass != '%gp' && strpos($url, '%u') === false && strpos($url, '%gu') === false) $ret = $this->caldav = new CalDAVClient(trim($url), trim($user), trim($pass), trim($auth)); if(!$ret){ write_log('calendar',"CalDAV Invalid URL: '".$account['url']."'"); $ret = $this->caldav = new CalDAVClient('', '', '', ''); } } } private function q($str) { return $this->rcmail->db->quoteIdentifier($str); } private function table($str) { return $this->rcmail->db->quoteIdentifier(get_table_name($str)); } private function generateId(){ $letters="abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for($i = 0; $i<=6; $i++){ $rndStr .= $letters[(rand() % strlen($letters))]; } $icalStamp = date("Ymd\THis\Z"); return $icalStamp."-".$rndStr; } private function syncCalDAV($events,$request='PUT',$categories=false){ $return = false; if($this->type == 'caldav'){ $event = $this->utils->exportEvents(0,0,$events); $caldav_props = unserialize($events[0]['caldav']); $this->connect($this->account['url'], $this->account['user'], $this->account['pass'], $this->account['auth']); if($categories){ $caldavs = $this->caldavs; if(!empty($caldavs[$categories])){ $this->connect($caldavs[$categories]['url'],$caldavs[$categories]['user'],$caldavs[$categories]['pass'],$caldavs[$categories]['auth']); } } if($request == 'DELETE'){ $this->caldav->DoDELETERequest($caldav_props[0] . '.ics'); $return = true; } else if($request == 'PUT'){ $ret = $this->caldav->DoPUTRequest($caldav_props[0].'.ics', $event, $caldav_props[1]); if($ret){ if(stripos($ret,'HTTP/1.1') !== false){ if(stripos($ret,'HTTP/1.1 204') !== false || $caldav_props[2] == '*'){ $ret = $this->caldav->GetEntryByHref($caldav_props[0]); $count = preg_match('/Etag:(.*?)\n/i',$ret,$temp); if($count > 0){ $etag = trim(str_replace('"','',$temp[1])); $caldav_props = array($caldav_props[0], $etag, $caldav_props[2]); } } else{ $caldav_props = null; } } else{ $caldav_props = array($caldav_props[0], $ret, $caldav_props[2]); } if(is_array($caldav_props)){ $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('caldav')."=? WHERE ".$this->q('uid')."=? AND ".$this->q('user_id')."=?", serialize($caldav_props), $events[0]['uid'], $this->rcmail->user->ID ); $return = true; } else{ $this->replicateEvents($events[0]['start'],$events[0]['start'] + 86400,$events[0]['categories']); } } } } else{ $return = true; } return $return; } public function searchEvents($str) { if (!empty($this->rcmail->user->ID)) { $cal_searchset = $this->rcmail->config->get('cal_searchset', array('summary')); $all_day = ''; $str = str_replace(array('\\'),array(''),$str); $str = str_replace('%','\%',$str); $str = str_replace('*','%',$str); $method = 'LIKE'; $wildcard = '%'; if(strlen($str) > 2){ $sql_filter = " AND (" . $this->rcmail->db->ilike($cal_searchset[0], $wildcard.$str.$wildcard); if(count($cal_searchset) > 1){ for($i=1;$iq('all_day') . "=1"; } else{ $sql_filter .= " OR " . $this->rcmail->db->ilike($cal_searchset[$i], $wildcard.$str.$wildcard); } } $sql_filter .= ")"; } $sql_result = $this->rcmail->db->query( "SELECT * FROM ".$this->table('events'). " WHERE " . $this->q('del') . "<>1". " AND " . $this->q('user_id') . "=?". $all_day. $sql_filter. " ORDER BY " . $this->q('summary'), $this->rcmail->user->ID); while ($sql_result && ($sql_arr = $this->rcmail->db->fetch_assoc($sql_result))) { $results[$sql_arr['event_id']] = $sql_arr; } if(!$_SESSION['removelayers']){ $events_table = $this->rcmail->config->get('db_table_events', 'events'); $this->rcmail->config->set('db_table_events',$this->rcmail->config->get('db_table_events_cache', 'events_cache')); $sql_result = $this->rcmail->db->query( "SELECT * FROM ".$this->table('events'). " WHERE " . $this->q('del') . "<>1". " AND " . $this->q('user_id') . "=?". $all_day. $sql_filter. " ORDER BY " . $this->q('summary'), $this->rcmail->user->ID); while ($sql_result && ($sql_arr = $this->rcmail->db->fetch_assoc($sql_result))) { $results['c'.$sql_arr['event_id']] = $sql_arr; } $feeds = array_merge((array)$this->rcmail->config->get('public_calendarfeeds',array()),(array)$this->rcmail->config->get('calendarfeeds',array())); foreach($feeds as $url => $category){ $arr = parse_url($url); if($arr['path'] == './'){ if($_SERVER['HTTPS']) $https = 's'; else $https = ''; $url = 'http' . $https . "://" . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . substr($url,1); $arr = parse_url($url); } $con = '?'; if(strstr($url,'?')) $con = '&'; if(stripos($arr['query'],'plugin.calendar_showlayer') && strtolower($arr['host']) == strtolower($_SERVER['HTTP_HOST'])){ $user_id = $this->rcmail->user->ID; $temparr = explode('&',$arr['query']); foreach($temparr as $key => $val){ if(strpos($val,'_userid=') === 0){ $temp = explode("=",$val); $remote_user = $temp[1]; $this->rcmail->user->ID = $remote_user; $sql_result = $this->rcmail->db->query( "SELECT * FROM ".$this->table('events'). " WHERE " . $this->q('del') . "<>1". " AND " . $this->q('user_id') . "=?". $all_day. $sql_filter. " ORDER BY " . $this->q('summary'), $this->rcmail->user->ID); while ($sql_result && ($sql_arr = $this->rcmail->db->fetch_assoc($sql_result))) { $results['c'.$sql_arr['event_id']] = $sql_arr; } $this->rcmail->user->ID = $user_id; break; } } } } $this->rcmail->config->set('db_table_events', $events_table); $arr = $this->utils->getUser($remote_user); $prefs = unserialize($arr['preferences']); $events_table = $this->rcmail->config->get('db_table_events', 'events'); $db_table = str_replace('_caldav','',$events_table); $map = $this->rcmail->config->get('backend_db_table_map',array()); if($prefs['backend'] == 'caldav'){ $db_table .= $map['caldav']; } else{ $db_table .= $map['database']; } foreach($feeds as $url => $category){ $arr = parse_url($url); $con = '?'; if(strstr($url,'?')) $con = '&'; if(stripos($arr['query'],'plugin.calendar_showlayer') && strtolower($arr['host']) == strtolower($_SERVER['HTTP_HOST'])){ $user_id = $this->rcmail->user->ID; $temparr = explode('&',$arr['query']); foreach($temparr as $key => $val){ if(strpos($val,'_userid=') === 0){ $temp = explode("=",$val); $remote_user = $temp[1]; $this->rcmail->user->ID = $remote_user; $sql_result = $this->rcmail->db->query( "SELECT * FROM ".$db_table. " WHERE " . $this->q('del') . "<>1". " AND " . $this->q('user_id') . "=?". $all_day. $sql_filter. " ORDER BY " . $this->q('summary'), $this->rcmail->user->ID); while ($sql_result && ($sql_arr = $this->rcmail->db->fetch_assoc($sql_result))) { $results[$sql_arr['event_id']] = $sql_arr; } $this->rcmail->user->ID = $user_id; break; } } } } $this->rcmail->config->set('db_table_events', $events_table); } } } if(is_array($results)){ $ret = $results; } else $ret = false; return $ret; } public function scheduleReminders($event){ if (!empty($this->rcmail->user->ID) && $event) { $map = $this->rcmail->config->get('backend_db_table_map'); if(stripos($this->table('events'),$map['caldav'])){ $col = 'caldav'; } else{ if($this->rcmail->config->get('db_table_events_cache') == get_table_name('events')){ $col = 'cache'; } else{ $col = 'events'; } } $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('reminders') . " WHERE ".$this->q($col)."=? AND ".$this->q('user_id')."=?", $event['event_id'], $this->rcmail->user->ID ); if($event['del'] == '1'){ return; } if($event['recurring'] != 0){ $events = $this->getEvents( time() - 86400, time() + 86400, array(), false, array('uid',$event['uid']) ); } else{ $events[0] = $event; } if(is_array($events)){ $start = time(); $props = array(); $props['user_id'] = $this->rcmail->user->ID; if($_SESSION['username']) $props['username'] = $_SESSION['username']; else{ $user = $this->utils->getUser($props['user_id']); $props['username'] = $user['username']; } $props['user_data'] = $this->rcmail->user->data; $props['lang'] = $this->rcmail->user->language; foreach($events as $key => $event){ if($event['reminderservice'] != '0'){ $next = $event['start'] - $event['reminder']; $schedule = false; if($event['reminderservice'] == 'popup'){ if(!$event['remindersent']) $schedule = true; // schedule missed reminders if($next > $start) $schedule = true; // always schedule future reminders } else if($event['reminderservice'] == 'email'){ if($next > $start && $event['clone']) $schedule = true; // schedule future reminders for recurring events if(!$event['remindersent'] && !$event['clone'] && $next > $start) $schedule = true; // schedule future reminders for single events if(!empty($this->caldavs[$event['categories']])){ if($this->caldavs[$event['categories']]['extr'] == 'external') $schedule = false; } else{ if($this->account['extr'] == 'external') $schedule = false; } } if($schedule){ $mapped = $this->utils->eventArrayMap($event); $props['event'] = $mapped; $props['ics'] = $this->utils->exportEvents(0,0,array(0=>$event), false, true); $query = $this->rcmail->db->query( "INSERT INTO " . $this->table('reminders') . " (". $this->q('user_id').", ". $this->q($col).", ". $this->q('type').", ". $this->q('props').", ". $this->q('runtime').") VALUES (?, ?, ?, ?, ?)", $this->rcmail->user->ID, $event['event_id'], $event['reminderservice'], serialize($props), $next ); if($event['reminderservice'] == 'email'){ break; } } } } } } } public function newEvent( $start, $end, $summary, $description, $location, $categories, $allDay, $recur, $expires, $occurrences, $byday=false, $bymonth=false, $bymonthday=false, $recurrence_id=false, $exdates=false, $reminderbefore=false, $remindertype=false, $remindermailto=false, $uid=false, $client=false ) { if (!empty($this->rcmail->user->ID)) { $srecur = (string) $recur; $rr = substr($recur,0,1); $recur = substr($recur,1); // PostgreSQL sets 'f' instead of '0' for false, which messes up our conditionals! if ($byday==false) $byday='0'; if ($bymonth==false) $bymonth='0'; if ($bymonthday==false) $bymonthday='0'; if ($recurrence_id==false) $recurrence_id='0'; if ($exdates==false) $exdates='0'; if ($recur==false) $recur='0'; if ($reminderbefore==false) $reminderbefore='0'; if ($remindertype==false) $remindertype='0'; if ($remindermailto==false) $remindermailto='0'; if ($uid==false) $uid='0'; if ($client==false) $client='0'; // if(!$uid) $uid = $this->generateId(); $exists = $this->getEventByUID($uid, $recurrence_id); if(is_array($exists)){ if($exists['del'] != '0'){ $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('del')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", 0, $exists['event_id'], $this->rcmail->user->ID ); } if( $start != $exists['start'] || $end != $exists['end'] || $summary != $exists['summary'] || $description != $exists['description'] || $location != $exists['location'] || $categories != $exists['categories'] || $recurrence_id != $exists['recurrence_id'] || $exdates != $exists['exdates'] || $reminderbefore != $exists['reminder'] || $remindertype != $exists['reminderservice'] || $remindermailto != $exists['remindermailto'] || $srecur != $exists['rr'] . $exists['recurring'] || $expires != $exists['expires'] || $occurences != $exists['occurences'] || $byday != $exists['byday'] || $bymonth != $exists['bymonth'] || $bymonthday != $exists['bymonthday'] || $allDay != $exists['all_day'] ){ $ret = $this->editEvent( $exists['event_id'], $start, $end, $summary, $description, $location, $categories, $srecur, $expires, $occurrences, $byday, $bymonth, $bymonthday, $recurrence_id, $exdates, $reminderbefore, $remindertype, $remindermailto, $allDay ); } else{ $ret = $exists; } $ret['edit'] = 1; return $ret; } $query = $this->rcmail->db->query( "INSERT INTO " . $this->table('events') . " (". $this->q('user_id').", ". $this->q('start').", ". $this->q('end').", ". $this->q('summary').", ". $this->q('description').", ". $this->q('location').", ". $this->q('categories').", ". $this->q('all_day').", ". $this->q('recurring').", ". $this->q('rr').", ". $this->q('expires').", ". $this->q('occurrences').", ". $this->q('byday').", ". $this->q('bymonth').", ". $this->q('bymonthday').", ". $this->q('reminder').", ". $this->q('reminderservice').", ". $this->q('remindermailto').", ". $this->q('remindersent').", ". $this->q('recurrence_id').", ". $this->q('exdates').", ". $this->q('uid').", ". $this->q('client').", ". $this->q('caldav').", ". $this->q('timestamp').") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $this->rcmail->user->ID, $start, $end, $summary, $description, $location, $categories, $allDay, $recur, $rr, $expires, $occurrences, $byday, $bymonth, $bymonthday, $reminderbefore, $remindertype, $remindermailto, 0, $recurrence_id, $exdates, $uid, $client, serialize(array(0 => $uid, 1 => false, 2 => '*')), date('Y-m-d H:i:s', time()) ); $id = $this->rcmail->db->insert_id($this->rcmail->config->get('db_sequencs_events')); $events = $this->getEventsByUID($uid); //find me: investigate why this is here ... if($this->rcmail->action == 'plugin.newEvent' || $this->rcmail->action == 'plugin.editEvent' || $this->rcmail->action == 'plugin.saveical' || $this->rcmail->action == 'plugin.calendar_upload' || $this->rcmail->action == 'plugin.moveEvent'|| $this->rcmail->action == 'plugin.resizeEvent' || $this->rcmail->action == 'plugin.calendar_showlayer'){ $events[0]['sync'] = $this->syncCalDAV($events,'PUT',$categories); } $this->calModified($this->rcmail->user->ID); $this->scheduleReminders($events[0]); return $events[0]; } } public function editEvent( $id, $start, $end, $summary, $description, $location, $categories, $recur, $expires, $occurrences, $byday=false, $bymonth=false, $bymonthday=false, $recurrence_id=false, $exdates=false, $reminderbefore=false, $remindertype=false, $remindermailto=false, $allDay=false, $old_categories=false ) { if (!empty($this->rcmail->user->ID)) { $srecur = $recur; $rr = substr($recur,0,1); $recur = substr($recur,1); // PostgreSQL sets 'f' instead of '0' for false, which messes up our conditionals! if ($byday==false) $byday='0'; if ($bymonth==false) $bymonth='0'; if ($bymonthday==false) $bymonthday='0'; if ($recurrence_id==false) $recurrence_id='0'; if ($exdates==false) $exdates='0'; if ($reminderbefore==false) $reminderbefore='0'; if ($remindertype==false) $remindertype='0'; if ($remindermailto==false) $remindermailto='0'; if ($allday==false) $allday='0'; if ($recurrence_id==false) $recurrence_id='0'; if ($recur==false) $recur='0'; if ($uid==false) $uid='0'; if ($client==false) $client='0'; // $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ". $this->q('summary')."=?, ". $this->q('start')."=?, ". $this->q('end')."=?, ". $this->q('description')."=?, ". $this->q('location')."=?, ". $this->q('categories')."=?, ". $this->q('rr')."=?, ". $this->q('recurring')."=?, ". $this->q('expires')."=?, ". $this->q('occurrences')."=?, ". $this->q('byday')."=?, ". $this->q('bymonth')."=?, ". $this->q('bymonthday')."=?, ". $this->q('recurrence_id')."=?, ". $this->q('exdates')."=?, ". $this->q('all_day')."=?, ". $this->q('reminder')."=?, ". $this->q('reminderservice')."=?, ". $this->q('remindermailto')."=?, ". $this->q('remindersent')."=?, ". $this->q('timestamp')."=?, ". $this->q('del')."=?, ". $this->q('notified')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", $summary, $start, $end, $description, $location, $categories, $rr, $recur, $expires, $occurrences, $byday, $bymonth, $bymonthday, $recurrence_id, $exdates, $allDay, $reminderbefore, $remindertype, $remindermailto, 0, date('Y-m-d H:i:s', time()), 0, 0, $id, $this->rcmail->user->ID ); $this->calModified($this->rcmail->user->ID); $event = $this->getEvent($id); // find me: get uid from GUI and calendar.php $events = $this->getEventsByUID($event['uid']); $this->scheduleReminders($events[0]); if($this->type == 'caldav'){ //find me: investigate why this is here ... if($this->rcmail->action == 'plugin.editEvent' || $this->rcmail->action == 'plugin.newEvent' || $this->rcmail->action == 'plugin.calendar_upload' || $this->rcmail->action == 'plugin.calendar_showlayer'){ $caldavs = $this->caldavs; if($categories != $old_categories){ if(!empty($caldavs[$old_categories]) || !empty($caldavs[$categories])){ $sync = $this->newEvent($start, $end, $summary, $description, $location, $categories, $allDay, $srecur, $expires, $occurrences, $byday, $bymonth, $bymonthday); if($sync) $events[0] = $this->removeEvent($id, $old_categories); } else{ $events[0]['sync'] = $this->syncCalDAV($events); } } else{ $events[0]['sync'] = $this->syncCalDAV($events); } } } else{ $events[0]['sync'] = true; } return $events[0]; } } public function moveEvent( $id, $start, $end, $allDay, $reminder ) { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('start')."=?, ". $this->q('end')."=?, ". $this->q('all_day')."=?, ". $this->q('remindersent')."=?, ". $this->q('timestamp')."=?, ". $this->q('notified')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", $start, $end, $allDay, 0, date('Y-m-d H:i:s', time()), 0, $id, $this->rcmail->user->ID ); $this->calModified($this->rcmail->user->ID); $event = $this->getEvent($id); // find me: get uid from GUI and calendar.php $events = $this->getEventsByUID($event['uid']); if($this->rcmail->action == 'plugin.moveEvent'){ $events[0]['sync'] = $this->syncCalDAV($events,'PUT',$events[0]['categories']); } $this->scheduleReminders($events[0]); return $events[0]; } } public function resizeEvent( $id, $start, $end, $reminder ) { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('start')."=?, ". $this->q('end')."=?, ". $this->q('remindersent')."=?, ". $this->q('timestamp')."=?, ". $this->q('notified')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", $start, $end, 0, date('Y-m-d H:i:s', time()), 0, $id, $this->rcmail->user->ID ); $this->calModified($this->rcmail->user->ID); $event = $this->getEvent($id); // find me: get uid from GUI and calendar.php $events = $this->getEventsByUID($event['uid']); if($this->rcmail->action == 'plugin.resizeEvent'){ $events[0]['sync'] = $this->syncCalDAV($events,'PUT',$events[0]['categories']); } $this->scheduleReminders($events[0]); return $events[0]; } } public function removeEvent($id, $categories=false) { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('del')."=?, ".$this->q('timestamp')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", 1, date('Y-m-d H:i:s', time()), $id, $this->rcmail->user->ID ); $event = $this->getEvent($id); // find me: get uid from GUI and calendar.php $events = $this->getEventsByUID($event['uid']); //find me: investigate why this is here ... if($this->rcmail->action == 'plugin.editEvent' || $this->rcmail->action == 'plugin.removeEvent' || $this->rcmail->action == 'plugin.calendar_showlayer'){ $caldav_props = unserialize($event['caldav']); $caldavs = $this->caldavs; if($event['recurrence_id'] != 0){ $initialevent = $this->getEventByUID($event['uid']); if($initialevent['exdates']){ $exdates = (array) @unserialize($initialevent['exdates']); $exdates[] = (int) $event['start']; } else{ $exdates = array((int) $event['start']); } $initialevent['exdates'] = serialize($exdates); $initialevent['recurrence_id'] = null; $events[0]['sync'] = $this->syncCalDAV(array(0 => $initialevent),'PUT',$initialevent['categories']); } else{ if(!$categories) $categories = $events[0]['categories']; $events[0]['sync'] = $this->syncCalDAV($events,'DELETE',$categories); } } $this->calModified($this->rcmail->user->ID); $this->scheduleReminders($events[0]); return $events[0]; } } public function purgeEvents() { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('del')."<>?", $this->rcmail->user->ID, 0 ); } } public function removeDuplicate($id) { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('event_id')."=?", $this->rcmail->user->ID, $id ); $this->calModified($this->rcmail->user->ID, true); } } public function truncateEvents($mode=0) { if (!empty($this->rcmail->user->ID)) { if($mode == 0){ $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('del')."=?", $this->rcmail->user->ID, 1 ); $this->calModified($this->rcmail->user->ID, true); } else if($mode == 1){ $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('del')."=?, ".$this->q('timestamp')."=? WHERE ".$this->q('user_id')."=?", 2, date('Y-m-d H:i:s', time()), $this->rcmail->user->ID ); } else if($mode == 2){ $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('del')."=?, ".$this->q('timestamp')."=? WHERE ".$this->q('user_id')."=?", 0, date('Y-m-d H:i:s', time()), $this->rcmail->user->ID ); } else if($mode == 3){ $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=?", $this->rcmail->user->ID ); } } } public function exportEvents($categories=false){ if($this->type == 'caldav'){ if($categories){ $caldavs = $this->caldavs; if(is_array($caldavs[$categories])){ $this->connect($caldavs[$categories]['url'],$caldavs[$categories]['user'],$caldavs[$categories]['pass'],$caldavs[$categories]['auth']); } } $response = trim($this->caldav->DoRequest()); $temparr = explode("\r\n\r\n", $response,2); return $temparr[1]; } } private function _getEvents( $estart, $eend, $category=false, $type='events' ) { if($this->type == 'caldav'){ $events = array(); $map = $this->rcmail->config->get('backend_db_table_map'); if(stripos($this->table('events'),$map['caldav'])){ $startYear = date('Y',$estart); $startMonth = date('m',$estart); $startDay = date('d',$estart); $endYear = date('Y',$eend ); $endMonth = date('m',$eend ); $endDay = date('d',$eend ); $caldavs = $this->caldavs; if(!$category || ($category && !$caldavs[$category])){ if($type == 'events'){ $events = (array) $this->caldav->GetEvents($startYear.$startMonth.$startDay."T000000Z",$endYear.$endMonth.$endDay."T000000Z"); } else if($type == 'alarms'){ // cron login successful ? if(method_exists($this->caldav, 'GetEventAlarms')){ $events = (array) $this->caldav->GetEventAlarms($startYear.$startMonth.$startDay."T000000Z",$endYear.$endMonth.$endDay."T000000Z"); } } } else{ if($category && $caldavs[$category]){ $caldav = $caldavs[$category]; $this->connect($caldav['url'],$caldav['user'],$caldav['pass'],$caldav['auth']); $startYear = date('Y',$estart); $startMonth = date('m',$estart); $startDay = date('d',$estart); if($type == 'events'){ $layers = (array) $this->caldav->GetEvents($startYear.$startMonth.$startDay."T000000Z",$endYear.$endMonth.$endDay."T000000Z"); } else if($type == 'alarms'){ $layers = (array) $this->caldav->GetEventAlarms($startYear.$startMonth.$startDay."T000000Z",$endYear.$endMonth.$endDay."T000000Z"); } foreach($layers as $key => $layer){ $layers[$key]['data'] = str_replace("\nCATEGORIES:","\nX-CATEGORIES:",$layers[$key]['data']); $insert = "\nCATEGORIES:" . $category; $layers[$key]['data'] = str_replace("\nBEGIN:VEVENT", "\nBEGIN:VEVENT" . $insert, $layers[$key]['data']); } $events = $layers; } } $concat = ''; foreach($events as $key => $val){ $insert = "\nX-HREF:".$val['href']."\nX-ETAG:".$val['etag']; $val['data'] = str_replace("\nBEGIN:VEVENT", "\nBEGIN:VEVENT" . $insert, $val['data']); $concat .= $val['data']; } if($concat != ''){ $this->utils->importEvents($concat); $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('timestamp')."=?, ".$this->q('notified')."=? WHERE ".$this->q('user_id')."=?", '0', '1', $this->rcmail->user->ID ); } } } } public function removeReminder( $id, $event_id, $ts ) { if (!empty($this->rcmail->user->ID)) { if(!$id && !$event_id){ $reminders = (array) $this->getReminders($ts); $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('reminders') . " WHERE " . $this->q('type') . "=? AND ".$this->q('user_id')."=? AND " . $this->q('runtime') . "rcmail->user->ID, $ts ); foreach($reminders as $reminder){ $query = $this->rcmail->db->query( "UPDATE " .$this->table('events') . " SET ". $this->q('remindersent')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", $ts, $reminder['id'], $this->rcmail->user->ID ); } } else{ $query = $this->rcmail->db->query( "DELETE FROM " . $this->table('reminders') . " WHERE " . $this->q('reminder_id') . "=? AND ".$this->q('user_id')."=?", $id, $this->rcmail->user->ID ); $query = $this->rcmail->db->query( "UPDATE " .$this->table('events') . " SET ". $this->q('remindersent')."=? WHERE ".$this->q('event_id')."=? AND ".$this->q('user_id')."=?", $ts, $event_id, $this->rcmail->user->ID ); } } } public function getReminders( $start, $type='popup' ) { $ret = array(); if (!empty($this->rcmail->user->ID)) { $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('reminders') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('runtime')."q('type')."=?", $this->rcmail->user->ID, $start, $type ); $reminders = array(); while ($result && ($reminder = $this->rcmail->db->fetch_assoc($result))) { $reminders[] = $reminder; } foreach($reminders as $key => $val){ $col = 'events'; if($val['caldav'] != '0') $col = 'caldav'; else if($val['cache'] != '0') $col = 'cache'; $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('event_id')."=?", $this->rcmail->user->ID, $val[$col] ); if($result){ $event = $this->rcmail->db->fetch_assoc($result); if($event['recurring'] != '0'){ $duration = 0; if($event['end'] != '0'){ $duration = (int) $event['end'] - (int) $event['start']; } $start = (int) $val['runtime'] + (int) $event['reminder']; $end = $start + $duration; $event['start'] = $start; if($event['end'] != '0'){ $event['end'] = $start + $duration; } } $event['reminder_id'] = $val['reminder_id']; $ret[$event['start'] . $event['uid'] . $event['event_id']] = $this->utils->eventArrayMap($event); } } } return $ret; } public function replicateEvents( $estart, $eend, $category=false, $type='events' ){ if (!empty($this->rcmail->user->ID)) { $this->_getEvents($estart, $eend, $category, $type); } } public function getEvents( $estart, $eend, $labels=array(), $category=false, $filter=false, $client=false, $type='events' ) { if (!empty($this->rcmail->user->ID)) { $mem_limit = (int) ini_get('memory_limit'); $start = -1; $end = $eend + 1; if($filter){ $filterfield = $filter[0]; $filtercomp = '=?'; $filterval = $filter[1]; } else{ $filterfield = 'del'; $filtercomp = '<>?'; $filterval = 1; } $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ". $this->q('start').">? AND ". $this->q('start')."q($filterfield) . $filtercomp, $this->rcmail->user->ID, $start, $end, $filterval ); $events = array(); while ($result && ($event = $this->rcmail->db->fetch_assoc($result))) { if($this->rcmail->action == 'plugin.getEvents'){ $db_category = $event['categories']; if($category){ if($db_category != $category){ continue; } } else{ $caldavs = $this->caldavs; if(!empty($caldavs[$db_category])){ continue; } } } // backwards compatibility if(empty($event['rr'])){ switch($event['recurring']){ case 86400: case 86401: $event['rr'] = 'd'; break; case 604800: case 1209600: case 1814400: case 2419200: $event['rr'] = 'w'; break; case 2592000: $event['rr'] = 'm'; break; case 31536000: $event['rr'] = 'y'; break; } } $append = $event['start']; $add = true; if($event['exdates']){ $exdates = @unserialize($event['exdates']); if(is_array($exdates) && count($exdates) > 0){ $exdates = $this->utils->array_flatten($exdates); $exdates = array_flip($exdates); if(isset($exdates[$event['start']])){ $add = false; } } } if($event['recurrence_id']){ $append = $event['recurrence_id']; } if($event['start'] >= $estart || $event['end'] >= $estart || $event['recurring'] != 0){ if($event['start'] >= $estart || $event['end'] >= $estart){ if($add){ $events[md5($event['uid'].$append)]=array( 'event_id' => (int) $event['event_id'], 'uid' => (string) $event['uid'], 'start' => (int) $event['start'], 'end' => (int) $event['end'], 'expires' => (string) $event['expires'], 'rr' => (string) $event['rr'], 'recur' => (string) $event['recurring'], 'occurrences' => (int) $event['occurrences'], 'recurrence_id' => (string) $event['recurrence_id'], 'summary' => (string) $event['summary'], 'description' => (string) $event['description'], 'location' => (string) $event['location'], 'categories' => (string) $event['categories'], 'all_day' => (int) $event['all_day'], 'timestamp' => (string) $event['timestamp'], 'del' => (int) $event['del'], 'notified' => (int) $event['notified'], 'byday' => (string) $event['byday'], 'bymonth' => (string) $event['bymonth'], 'bymonthday' => (string) $event['bymonthday'], 'reminder' => (int) $event['reminder'], 'reminderservice' => (string) $event['reminderservice'], 'remindermailto' => (string) $event['remindermailto'], 'editable' => true, 'clone' => false ); } } if($event['recurring'] != 0 && !$client){ $rrule = $this->utils->rrule($event); if($rrule){ $basedate = date('Ymd\THis',$event['start']); $rule = new RRule(new iCalDate($basedate), $rrule); do{ $date = $rule->GetNext(); if(isset($date)){ $clone_date = $date->Render(); $clone_start = strtotime($clone_date); $clone_end = strtotime($clone_date) + $event['end'] - $event['start']; $dst_adjust = 0; if(date('I', $event['start']) != date('I', $clone_start)){ if(date('I',$event['start']) == 0 && date('I',$clone_start) == 1) $dst_adjust = 3600; else $dst_adjust = -3600; } $clone_start = $clone_start + $dst_adjust; $clone_end = $clone_end + $dst_adjust; if($clone_start > $event['start'] && $clone_start > $estart){ if(!isset($exdates[$clone_start])){ if($add){ $set_clone = (string) $event['start']; $set_clone_end = (string) $event['end']; } else{ $set_clone = false; $set_clone_end = false; $add = true; } $event['editable'] = true; $event['recur'] = $event['recurring']; $events[md5($event['uid'].$clone_start)] = array( 'event_id' => (int) $event['event_id'], 'uid' => (string) $event['uid'], 'start' => (int) $clone_start, 'end' => (int) $clone_end, 'expires' => (string) $event['expires'], 'rr' => (string) $event['rr'], 'recur' => (string) $event['recurring'], 'occurrences' => (int) $event['occurrences'], 'recurrence_id' => (string) $event['recurrence_id'], 'summary' => (string) $event['summary'], 'description' => (string) $event['description'], 'location' => (string) $event['location'], 'categories' => (string) $event['categories'], 'all_day' => (int) $event['all_day'], 'timestamp' => (string) $event['timestamp'], 'del' => (int) $event['del'], 'byday' => (string) $event['byday'], 'bymonth' => (string) $event['bymonth'], 'bymonthday' => (string) $event['bymonthday'], 'reminder' => (int) $event['reminder'], 'reminderservice' => (string) $event['reminderservice'], 'remindermailto' => (string) $event['remindermailto'], 'editable' => (bool) $event['editable'], 'clone' => $set_clone, 'clone_end' => $set_clone_end, 'caldav' => (string) $event['caldav'], 'notified' => (int) $event['notified'], 'initial' => (array) $this->utils->eventArrayMap($event) ); } } } } while(isset($date) && strtotime($date->Render()) <= $eend); } } } } $public_caldavs = $this->rcmail->config->get('public_caldavs', array()); foreach($events as $key => $event){ $category = $event['categories']; if(!empty($public_caldavs[$category]) && $public_caldavs[$category]['readonly']){ $events[$key]['editable'] = false; } } return $events; } } private function calModified($userid=false,$del=false) { if($userid && !$del){ file_put_contents('./plugins/calendar/temp/' . $userid . '.pid', time()); } if($userid && $del){ @unlink('./plugins/calendar/temp/' . $userid . '.pid'); } } public function removeTimestamps() { if (!empty($this->rcmail->user->ID)) { $query = $this->rcmail->db->query( "UPDATE " . $this->table('events') . " SET ".$this->q('timestamp')."=? WHERE ".$this->q('user_id')."=?", '0', $this->rcmail->user->ID ); } } public function getEvent($eventid){ if (!empty($this->rcmail->user->ID)) { $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('event_id')."=?", $this->rcmail->user->ID, $eventid ); $event = $this->rcmail->db->fetch_assoc($result); if($event){ $event['recur'] = $event['recurring']; return $event; } } return array(); } public function getEventByUID($uid, $recurrence_id=0){ $event = array(); if (!empty($this->rcmail->user->ID)) { $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('uid')."=? AND ".$this->q('recurrence_id')."=?", $this->rcmail->user->ID, $uid, $recurrence_id ); while ($result && ($event = $this->rcmail->db->fetch_assoc($result))){ $events[] = $event; } if(is_array($events) && count($events) > 1) write_log('calendar', "ERROR: Event with UID " . $event['uid'] . " is not unique"); $event = $events[0]; } return $event; } public function getEventsByUID($uid){ if (!empty($this->rcmail->user->ID)) { $result = $this->rcmail->db->query( "SELECT * FROM " . $this->table('events') . " WHERE ".$this->q('user_id')."=? AND ".$this->q('uid')."=?", $this->rcmail->user->ID, $uid ); while ($result && ($event = $this->rcmail->db->fetch_assoc($result))){ $temparr[] = $event; } } $i = 0; $events = array(); if(is_array($temparr)){ foreach($temparr as $key => $event){ if(!$event['recurrence_id']){ if(!empty($events[0])) write_log('calendar', "ERROR: Event with UID " . $event['uid'] . " is not unique"); $events[0] = $event; } else{ $events[$i] = $event; } $i++; } } return $events; } public function test($str = 'db_table_events') { $this->rcmail->db->db_handle->loadModule('Manager'); if(!PEAR::isError($result = $this->rcmail->db->db_handle->listTableFields($this->rcmail->config->get($str)))) $ret = $result; else $ret = array(); return $ret; } } ?>