ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:25.85 GB of 70.42 GB (36.71%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ http/ mail.1/ plugins/ calendar/ lib/ - drwxrwxr-x

Directory:
Viewing file:     calendar_ical.php (14.55 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

/**
 * iCalendar functions for the Calendar plugin
 *
 * @version 0.7-beta
 * @author Lazlo Westerhof <hello@lazlo.me>
 * @author Thomas Bruederli <bruederli@kolabsys.com>
 * @author Bogomil "Bogo" Shopov <shopov@kolabsys.com>
 *
 * Copyright (C) 2010, Lazlo Westerhof - Netherlands
 * Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Additional permission is granted to distribute and use this file under
 * the terms of the GNU General Public License Version 2 in conjunction with
 * the Roundcube Web Mailer Version 0.7 as distributed by the Roundcube
 * Community (http://roundcube.net).
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


/**
 * Class to parse and build vCalendar (iCalendar) files
 *
 * Uses the Horde:iCalendar class for parsing. To install:
 * > pear channel-discover pear.horde.org
 * > pear install horde/Horde_Icalendar
 *
 */
class calendar_ical
{
  const 
EOL "\r\n";
  
  private 
$rc;
  private 
$cal;
  private 
$timezone 'Z';
  
  public 
$method;
  public 
$events = array();

  function 
__construct($cal)
  {
    
$this->cal $cal;
    
$this->rc $cal->rc;
    
    
// compose timezone string
    
if ($cal->timezone) {
      
$hours floor($cal->timezone $cal->dst_active);
      
$this->timezone sprintf('%s%02d:%02d', ($hours >= '+' ''), $hours, ($cal->timezone $hours) * 60);
    }
  }

  
/**
   * Import events from iCalendar format
   *
   * @param  string vCalendar input
   * @param  string Input charset (from envelope)
   * @return array List of events extracted from the input
   */
  
public function import($vcal$charset RCMAIL_CHARSET)
  {
    
$parser $this->get_parser();
    
$parser->parsevCalendar($vcal'VCALENDAR'$charset);
    
$this->method $parser->getAttributeDefault('METHOD''');
    
$this->events $seen = array();
    if (
$data $parser->getComponents()) {
      foreach (
$data as $comp) {
        if (
$comp->getType() == 'vEvent') {
          
$event $this->_to_rcube_format($comp);
          if (!
$seen[$event['uid']]++)
            
$this->events[] = $event;
        }
      }
    }
    
    return 
$this->events;
  }

  
/**
   * Read iCalendar events from a file
   *
   * @param string File path to read from
   * @return array List of events extracted from the file
   */
  
public function import_from_file($filepath)
  {
    
$this->events $seen = array();
    
$fp fopen($filepath'r');

    
// check file content first
    
$begin fread($fp1024);
    if (!
preg_match('/BEGIN:VCALENDAR/i'$begin))
      return 
$this->events;

    
$parser $this->get_parser();
    
$buffer '';

    
fseek($fp0);
    while ((
$line fgets($fp2048)) !== false) {
      
$buffer .= $line;
      if (
preg_match('/END:VEVENT/i'$line)) {
        
$parser->parsevCalendar($buffer'VCALENDAR'RCMAIL_CHARSETfalse);
        
$buffer '';
      }
    }
    
fclose($fp);

    if (
$data $parser->getComponents()) {
      foreach (
$data as $comp) {
        if (
$comp->getType() == 'vEvent') {
          
$event $this->_to_rcube_format($comp);
          if (!
$seen[$event['uid']]++)
            
$this->events[] = $event;
        }
      }
    }

    return 
$this->events;
  }

  
/**
   * Load iCal parser from the Horde lib
   */
  
private function get_parser()
  {
    
// use Horde:iCalendar to parse vcalendar file format
    
require_once 'Horde/iCalendar.php';

    
// set target charset for parsed events
    
$GLOBALS['_HORDE_STRING_CHARSET'] = RCMAIL_CHARSET;

    return new 
Horde_iCalendar;
  }

  
/**
   * Convert the given File_IMC_Parse_Vcalendar_Event object to the internal event format
   */
  
private function _to_rcube_format($ve)
  {
    
$event = array(
      
'uid' => $ve->getAttributeDefault('UID'),
      
'changed' => $ve->getAttributeDefault('DTSTAMP'0),
      
'title' => $ve->getAttributeDefault('SUMMARY'),
      
'start' => $ve->getAttribute('DTSTART'),
      
'end' => $ve->getAttribute('DTEND'),
      
// set defaults
      
'free_busy' => 'busy',
      
'priority' => 0,
    );
    
    
// check for all-day dates
    
if (is_array($event['start'])) {
      
// create timestamp at 12:00 in user's timezone
      
$event['start'] = $this->_date2time($event['start']);
      
$event['allday'] = true;
    }
    if (
is_array($event['end'])) {
      
$event['end'] = $this->_date2time($event['end']) - 23 3600;
    }

    
// map other attributes to internal fields
    
$_attendees = array();
    foreach (
$ve->getAllAttributes() as $attr) {
      switch (
$attr['name']) {
        case 
'ORGANIZER':
          
$organizer = array(
            
'name' => $attr['params']['CN'],
            
'email' => preg_replace('/^mailto:/i'''$attr['value']),
            
'role' => 'ORGANIZER',
            
'status' => 'ACCEPTED',
          );
          if (isset(
$_attendees[$organizer['email']])) {
            
$i $_attendees[$organizer['email']];
            
$event['attendees'][$i]['role'] = $organizer['role'];
          }
          break;
        
        case 
'ATTENDEE':
          
$attendee = array(
            
'name' => $attr['params']['CN'],
            
'email' => preg_replace('/^mailto:/i'''$attr['value']),
            
'role' => $attr['params']['ROLE'] ? $attr['params']['ROLE'] : 'REQ-PARTICIPANT',
            
'status' => $attr['params']['PARTSTAT'],
            
'rsvp' => $attr['params']['RSVP'] == 'TRUE',
          );
          if (
$organizer && $organizer['email'] == $attendee['email'])
            
$attendee['role'] = 'ORGANIZER';
          
          
$event['attendees'][] = $attendee;
          
$_attendees[$attendee['email']] = count($event['attendees']) - 1;
          break;
          
        case 
'TRANSP':
          
$event['free_busy'] = $attr['value'] == 'TRANSPARENT' 'free' 'busy';
          break;
        
        case 
'STATUS':
          if (
$attr['value'] == 'TENTATIVE')
            
$event['free_busy'] == 'tentative';
          break;
        
        case 
'PRIORITY':
          if (
is_numeric($attr['value'])) {
            
$event['priority'] = $attr['value'];
          }
          break;
        
        case 
'RRULE':
          
// parse recurrence rule attributes
          
foreach (explode(';'$attr['value']) as $par) {
            list(
$k$v) = explode('='$par);
            
$params[$k] = $v;
          }
          if (
$params['UNTIL'])
            
$params['UNTIL'] = $ve->_parseDateTime($params['UNTIL']);
          if (!
$params['INTERVAL'])
            
$params['INTERVAL'] = 1;
          
          
$event['recurrence'] = $params;
          break;
        
        case 
'EXDATE':
          break;
          
        case 
'RECURRENCE-ID':
          
$event['recurrence_id'] = $this->_date2time($attr['value']);
          break;
        
        case 
'SEQUENCE':
          
$event['sequence'] = intval($attr['value']);
          break;
        
        case 
'DESCRIPTION':
        case 
'LOCATION':
          
$event[strtolower($attr['name'])] = $attr['value'];
          break;
        
        case 
'CLASS':
        case 
'X-CALENDARSERVER-ACCESS':
          
$sensitivity_map = array('PUBLIC' => 0'PRIVATE' => 1'CONFIDENTIAL' => 2);
          
$event['sensitivity'] = $sensitivity_map[$attr['value']];
          break;

        case 
'X-MICROSOFT-CDO-BUSYSTATUS':
          if (
$attr['value'] == 'OOF')
            
$event['free_busy'] == 'outofoffice';
          else if (
in_array($attr['value'], array('FREE''BUSY''TENTATIVE')))
            
$event['free_busy'] = strtolower($attr['value']);
          break;
      }
    }

    
// find alarms
    
if ($valarm $ve->findComponent('valarm')) {
      
$action 'DISPLAY';
      
$trigger null;
      
      foreach (
$valarm->getAllAttributes() as $attr) {
        switch (
$attr['name']) {
          case 
'TRIGGER':
            if (
$attr['params']['VALUE'] == 'DATE-TIME') {
              
$trigger '@' $attr['value'];
            }
            else {
              
$trigger $attr['value'];
              
$offset abs($trigger);
              
$unit 'S';
              if (
$offset 86400 == 0) {
                
$unit 'D';
                
$trigger intval($trigger 86400);
              }
              else if (
$offset 3600 == 0) {
                
$unit 'H';
                
$trigger intval($trigger 3600);
              }
              else if (
$offset 60 == 0) {
                
$unit 'M';
                
$trigger intval($trigger 60);
              }
            }
            break;

          case 
'ACTION':
            
$action $attr['value'];
            break;
        }
      }
      if (
$trigger)
        
$event['alarms'] = $trigger $unit ':' $action;
    }

    
// add organizer to attendees list if not already present
    
if ($organizer && !isset($_attendees[$organizer['email']]))
      
array_unshift($event['attendees'], $organizer);

    
// make sure the event has an UID
    
if (!$event['uid'])
      
$event['uid'] = $this->cal->$this->generate_uid();
    
    return 
$event;
  }
  
  
/**
   * Helper method to correctly interpret an all-day date value
   */
  
private function _date2time($prop)
  {
    
// create timestamp at 12:00 in user's timezone
    
return is_array($prop) ? strtotime(sprintf('%04d%02d%02dT120000%s'$prop['year'], $prop['month'], $prop['mday'], $this->timezone)) : $prop;
  }


  
/**
   * Free resources by clearing member vars
   */
  
public function reset()
  {
    
$this->method '';
    
$this->events = array();
  }

  
/**
   * Export events to iCalendar format
   *
   * @param  array   Events as array
   * @param  string  VCalendar method to advertise
   * @param  boolean Directly send data to stdout instead of returning
   * @return string  Events in iCalendar format (http://tools.ietf.org/html/rfc5545)
   */
  
public function export($events$method null$write false)
  {
      
$ical "BEGIN:VCALENDAR" self::EOL;
      
$ical .= "VERSION:2.0" self::EOL;
      
$ical .= "PRODID:-//Roundcube Webmail " RCMAIL_VERSION "//NONSGML Calendar//EN" self::EOL;
      
$ical .= "CALSCALE:GREGORIAN" self::EOL;
      
      if (
$method)
        
$ical .= "METHOD:" strtoupper($method) . self::EOL;
        
      if (
$write) {
        echo 
$ical;
        
$ical '';
      }
      
      foreach (
$events as $event) {
        
$vevent "BEGIN:VEVENT" self::EOL;
        
$vevent .= "UID:" self::escpape($event['uid']) . self::EOL;
        
$vevent .= "DTSTAMP:" gmdate('Ymd\THis\Z'$event['changed'] ? $event['changed'] : time()) . self::EOL;
        
// correctly set all-day dates
        
if ($event['allday']) {
          
$vevent .= "DTSTART;VALUE=DATE:" gmdate('Ymd'$event['start'] + $this->cal->gmt_offset) . self::EOL;
          
$vevent .= "DTEND;VALUE=DATE:" gmdate('Ymd'$event['end'] + $this->cal->gmt_offset 86400) . self::EOL;  // ends the next day
        
}
        else {
          
$vevent .= "DTSTART:" gmdate('Ymd\THis\Z'$event['start']) . self::EOL;
          
$vevent .= "DTEND:" gmdate('Ymd\THis\Z'$event['end']) . self::EOL;
        }
        
$vevent .= "SUMMARY:" self::escpape($event['title']) . self::EOL;
        
$vevent .= "DESCRIPTION:" self::escpape($event['description']) . self::EOL;
        
        if (!empty(
$event['attendees'])){
          
$vevent .= $this->_get_attendees($event['attendees']);
        }

        if (!empty(
$event['location'])) {
          
$vevent .= "LOCATION:" self::escpape($event['location']) . self::EOL;
        }
        if (
$event['recurrence']) {
          
$vevent .= "RRULE:" calendar::to_rrule($event['recurrence'], self::EOL) . self::EOL;
        }
        if(!empty(
$event['categories'])) {
          
$vevent .= "CATEGORIES:" self::escpape(strtoupper($event['categories'])) . self::EOL;
        }
        if (
$event['sensitivity'] > 0) {
          
$vevent .= "CLASS:" . ($event['sensitivity'] == 'CONFIDENTIAL' 'PRIVATE') . self::EOL;
        }
        if (
$event['alarms']) {
          list(
$trigger$action) = explode(':'$event['alarms']);
          
$val calendar::parse_alaram_value($trigger);
          
          
$vevent .= "BEGIN:VALARM\n";
          if (
$val[1]) $vevent .= "TRIGGER:" preg_replace('/^([-+])(.+)/''\\1PT\\2'$trigger) . self::EOL;
          else         
$vevent .= "TRIGGER;VALUE=DATE-TIME:" gmdate('Ymd\THis\Z'$val[0]) . self::EOL;
          if (
$action$vevent .= "ACTION:" self::escpape(strtoupper($action)) . self::EOL;
          
$vevent .= "END:VALARM\n";
        }
        
        
$vevent .= "TRANSP:" . ($event['free_busy'] == 'free' 'TRANSPARENT' 'OPAQUE') . self::EOL;
        
        if (
$event['priority']) {
          
$vevent .= "PRIORITY:" $event['priority'] . self::EOL;
        }
        
        if (
$event['cancelled'])
          
$vevent .= "STATUS:CANCELLED" self::EOL;
        else if (
$event['free_busy'] == 'tentative')
          
$vevent .= "STATUS:TENTATIVE" self::EOL;
        
        
// TODO: export attachments
        
        
$vevent .= "END:VEVENT" self::EOL;
        
        if (
$write)
          echo 
rcube_vcard::rfc2425_fold($vevent);
        else
          
$ical .= $vevent;
      }
      
      
$ical .= "END:VCALENDAR" self::EOL;
      
      if (
$write) {
        echo 
$ical;
        return 
true;
      }

      
// fold lines to 75 chars
      
return rcube_vcard::rfc2425_fold($ical);
  }
  
  private function 
escpape($str)
  {
    return 
preg_replace('/(?<!\\\\)([\:\;\,\\n\\r])/''\\\$1'$str);
  }

  
/**
  * Construct the orginizer of the event.
  * @param Array Attendees and roles
  *
  */
  
private function _get_attendees($ats)
  {
    
$organizer "";
    
$attendees "";
    foreach (
$ats as $at) {
      if (
$at['role']=="ORGANIZER") {
        
//I am an orginizer
        
$organizer .= "ORGANIZER;";
        if (!empty(
$at['name']))
          
$organizer .= 'CN="' $at['name'] . '"';
        
$organizer .= ":mailto:"$at['email'] . self::EOL;
      }
      else {
        
//I am an attendee 
        
$attendees .= "ATTENDEE;ROLE=" $at['role'] . ";PARTSTAT=" $at['status'];
        if (
$at['rsvp'])
          
$attendees .= ";RSVP=TRUE";
        if (!empty(
$at['name']))
          
$attendees .= ';CN="' $at['name'] . '"';
        
$attendees .= ":mailto:" $at['email'] . self::EOL;
      }
    }

    return 
$organizer $attendees;
  }

}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 5.1066 seconds