mirror of
https://github.com/YunoHost-Apps/z-push_ynh.git
synced 2024-09-03 18:05:58 +02:00
199 lines
9.4 KiB
PHP
199 lines
9.4 KiB
PHP
<?php
|
|
/***********************************************
|
|
* File : z_ical.php
|
|
* Project : Z-Push
|
|
* Descr : This is a very basic iCalendar parser
|
|
* used to process incoming meeting requests
|
|
* and responses.
|
|
*
|
|
* Created : 01.12.2008
|
|
*
|
|
* Copyright 2007 - 2013 Zarafa Deutschland GmbH
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation with the following additional
|
|
* term according to sec. 7:
|
|
*
|
|
* According to sec. 7 of the GNU Affero General Public License, version 3,
|
|
* the terms of the AGPL are supplemented with the following terms:
|
|
*
|
|
* "Zarafa" is a registered trademark of Zarafa B.V.
|
|
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
|
|
* The licensing of the Program under the AGPL does not imply a trademark license.
|
|
* Therefore any rights, title and interest in our trademarks remain entirely with us.
|
|
*
|
|
* However, if you propagate an unmodified version of the Program you are
|
|
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
|
|
* Furthermore you may use our trademarks where it is necessary to indicate
|
|
* the intended purpose of a product or service provided you use it in accordance
|
|
* with honest practices in industrial or commercial matters.
|
|
* If you want to propagate modified versions of the Program under the name "Z-Push",
|
|
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
|
|
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
|
|
*
|
|
* 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/>.
|
|
*
|
|
* Consult LICENSE file for details
|
|
************************************************/
|
|
|
|
class ICalParser{
|
|
private $props;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param mapistore $store
|
|
* @param array &$props properties to be set
|
|
*
|
|
* @access public
|
|
*/
|
|
public function ICalParser(&$store, &$props){
|
|
$this->props = $props;
|
|
}
|
|
|
|
/**
|
|
* Function reads calendar part and puts mapi properties into an array.
|
|
*
|
|
* @param string $ical the ical data
|
|
* @param array &$mapiprops mapi properties
|
|
*
|
|
* @access public
|
|
*/
|
|
public function ExtractProps($ical, &$mapiprops) {
|
|
//mapping between partstat in ical and MAPI Meeting Response classes as well as icons
|
|
$aClassMap = array(
|
|
"ACCEPTED" => array("class" => "IPM.Schedule.Meeting.Resp.Pos", "icon" => 0x405),
|
|
"DECLINED" => array("class" => "IPM.Schedule.Meeting.Resp.Neg", "icon" => 0x406),
|
|
"TENTATIVE" => array("class" => "IPM.Schedule.Meeting.Resp.Tent", "icon" => 0x407),
|
|
"NEEDS-ACTION" => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404), //iphone
|
|
"REQ-PARTICIPANT" => array("class" => "IPM.Schedule.Meeting.Request", "icon" => 0x404), //nokia
|
|
);
|
|
|
|
$aical = preg_split("/[\n]/", $ical);
|
|
$elemcount = count($aical);
|
|
$i=0;
|
|
$nextline = $aical[0];
|
|
|
|
//last element is empty
|
|
while ($i < $elemcount - 1) {
|
|
$line = $nextline;
|
|
$nextline = $aical[$i+1];
|
|
|
|
//if a line starts with a space or a tab it belongs to the previous line
|
|
while (strlen($nextline) > 0 && ($nextline{0} == " " || $nextline{0} == "\t")) {
|
|
$line = rtrim($line) . substr($nextline, 1);
|
|
$nextline = $aical[++$i + 1];
|
|
}
|
|
$line = rtrim($line);
|
|
|
|
switch (strtoupper($line)) {
|
|
case "BEGIN:VCALENDAR":
|
|
case "BEGIN:VEVENT":
|
|
case "END:VEVENT":
|
|
case "END:VCALENDAR":
|
|
break;
|
|
default:
|
|
unset ($field, $data, $prop_pos, $property);
|
|
if (preg_match ("/([^:]+):(.*)/", $line, $line)){
|
|
$field = $line[1];
|
|
$data = $line[2];
|
|
$property = $field;
|
|
$prop_pos = strpos($property,';');
|
|
if ($prop_pos !== false) $property = substr($property, 0, $prop_pos);
|
|
$property = strtoupper($property);
|
|
|
|
switch ($property) {
|
|
case 'DTSTART':
|
|
$data = $this->getTimestampFromStreamerDate($data);
|
|
$mapiprops[$this->props["starttime"]] = $mapiprops[$this->props["commonstart"]] = $mapiprops[$this->props["clipstart"]] = $mapiprops[PR_START_DATE] = $data;
|
|
break;
|
|
|
|
case 'DTEND':
|
|
$data = $this->getTimestampFromStreamerDate($data);
|
|
$mapiprops[$this->props["endtime"]] = $mapiprops[$this->props["commonend"]] = $mapiprops[$this->props["recurrenceend"]] = $mapiprops[PR_END_DATE] = $data;
|
|
break;
|
|
|
|
case 'UID':
|
|
$mapiprops[$this->props["goidtag"]] = $mapiprops[$this->props["goid2tag"]] = Utils::GetOLUidFromICalUid($data);
|
|
break;
|
|
|
|
case 'ATTENDEE':
|
|
$fields = explode(";", $field);
|
|
foreach ($fields as $field) {
|
|
$prop_pos = strpos($field, '=');
|
|
if ($prop_pos !== false) {
|
|
switch (substr($field, 0, $prop_pos)) {
|
|
case 'PARTSTAT' : $partstat = substr($field, $prop_pos+1); break;
|
|
case 'CN' : $cn = substr($field, $prop_pos+1); break;
|
|
case 'ROLE' : $role = substr($field, $prop_pos+1); break;
|
|
case 'RSVP' : $rsvp = substr($field, $prop_pos+1); break;
|
|
}
|
|
}
|
|
}
|
|
if (isset($partstat) && isset($aClassMap[$partstat]) &&
|
|
|
|
(!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
|
|
$mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$partstat]['class'];
|
|
$mapiprops[PR_ICON_INDEX] = $aClassMap[$partstat]['icon'];
|
|
}
|
|
// START ADDED dw2412 to support meeting requests on HTC Android Mail App
|
|
elseif (isset($role) && isset($aClassMap[$role]) &&
|
|
(!isset($mapiprops[PR_MESSAGE_CLASS]) || $mapiprops[PR_MESSAGE_CLASS] == "IPM.Schedule.Meeting.Request")) {
|
|
$mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$role]['class'];
|
|
$mapiprops[PR_ICON_INDEX] = $aClassMap[$role]['icon'];
|
|
}
|
|
// END ADDED dw2412 to support meeting requests on HTC Android Mail App
|
|
if (!isset($cn)) $cn = "";
|
|
$data = str_replace ("MAILTO:", "", $data);
|
|
$attendee[] = array ('name' => stripslashes($cn), 'email' => stripslashes($data));
|
|
break;
|
|
|
|
case 'ORGANIZER':
|
|
$field = str_replace("ORGANIZER;CN=", "", $field);
|
|
$data = str_replace ("MAILTO:", "", $data);
|
|
$organizer[] = array ('name' => stripslashes($field), 'email' => stripslashes($data));
|
|
break;
|
|
|
|
case 'LOCATION':
|
|
$data = str_replace("\\n", "<br />", $data);
|
|
$data = str_replace("\\t", " ", $data);
|
|
$data = str_replace("\\r", "<br />", $data);
|
|
$data = stripslashes($data);
|
|
$mapiprops[$this->props["tneflocation"]] = $mapiprops[$this->props["location"]] = $data;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
$i++;
|
|
|
|
}
|
|
$mapiprops[$this->props["usetnef"]] = true;
|
|
}
|
|
|
|
/**
|
|
* Converts an YYYYMMDDTHHMMSSZ kind of string into an unixtimestamp
|
|
*
|
|
* @param string $data
|
|
*
|
|
* @access private
|
|
* @return long
|
|
*/
|
|
private function getTimestampFromStreamerDate ($data) {
|
|
$data = str_replace('Z', '', $data);
|
|
$data = str_replace('T', '', $data);
|
|
|
|
preg_match ('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})([0-9]{0,2})/', $data, $regs);
|
|
if ($regs[1] < 1970) {
|
|
$regs[1] = '1971';
|
|
}
|
|
return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
|
|
}
|
|
}
|