mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
* Mail/Addressbook/Calendar: add and use charset when sending/receiving mails with vCard/iCals, change default vCard charset preference to utf-8
This commit is contained in:
parent
b74b3d84f4
commit
0eb3619cd1
@ -305,7 +305,7 @@ class addressbook_hooks
|
|||||||
'help' => 'Which charset should be used for the vCard import and export.',
|
'help' => 'Which charset should be used for the vCard import and export.',
|
||||||
'xmlrpc' => True,
|
'xmlrpc' => True,
|
||||||
'admin' => false,
|
'admin' => false,
|
||||||
'default'=> 'iso-8859-1',
|
'default'=> 'utf-8',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $settings;
|
return $settings;
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addressbook - vCard parser
|
* Addressbook - vCard parser
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class addressbook_vcal extends addressbook_bo
|
class addressbook_vcal extends addressbook_bo
|
||||||
{
|
{
|
||||||
@ -555,11 +556,17 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
$container = false;
|
$container = false;
|
||||||
$vCard = Horde_Icalendar::newComponent('vcard', $container);
|
$vCard = Horde_Icalendar::newComponent('vcard', $container);
|
||||||
|
|
||||||
if (!$vCard->parsevCalendar($_vcard, 'VCARD', $charset))
|
if ($charset && $charset != 'utf-8')
|
||||||
|
{
|
||||||
|
$_vcard = Api\Translation::convert($_vcard, $charset, 'utf-8');
|
||||||
|
}
|
||||||
|
if (!$vCard->parsevCalendar($_vcard, 'VCARD'))
|
||||||
{
|
{
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$vCard = $_vcard;
|
$vCard = $_vcard;
|
||||||
}
|
}
|
||||||
$vcardValues = $vCard->getAllAttributes();
|
$vcardValues = $vCard->getAllAttributes();
|
||||||
|
@ -230,7 +230,7 @@ app.classes.addressbook = AppJS.extend(
|
|||||||
extras.owner.push('c'+ids);
|
extras.owner.push('c'+ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(orgs.length > 0)
|
if(orgs.length > 0)
|
||||||
{
|
{
|
||||||
// Get organisation contacts, then show infolog list
|
// Get organisation contacts, then show infolog list
|
||||||
@ -704,13 +704,13 @@ app.classes.addressbook = AppJS.extend(
|
|||||||
adb_mail_vcard: function(_action, _elems)
|
adb_mail_vcard: function(_action, _elems)
|
||||||
{
|
{
|
||||||
var app_registry = egw.link_get_registry('mail');
|
var app_registry = egw.link_get_registry('mail');
|
||||||
if (typeof app_registry['view'] == 'undefined') app_registry = egw.link_get_registry('felamimail');
|
|
||||||
var link = egw().link("/index.php","menuaction="+app_registry['add']['menuaction']);
|
var link = egw().link("/index.php","menuaction="+app_registry['add']['menuaction']);
|
||||||
for (var i = 0; i < _elems.length; i++)
|
for (var i = 0; i < _elems.length; i++)
|
||||||
{
|
{
|
||||||
var idToUse = _elems[i].id;
|
var idToUse = _elems[i].id;
|
||||||
var idToUseArray = idToUse.split('::');
|
var idToUseArray = idToUse.split('::');
|
||||||
idToUse = idToUseArray[1];
|
idToUse = idToUseArray[1];
|
||||||
|
link += "&preset[type][]="+encodeURIComponent("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
|
||||||
link += "&preset[file][]="+encodeURIComponent("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
link += "&preset[file][]="+encodeURIComponent("vfs://default/apps/addressbook/"+idToUse+"/.entry");
|
||||||
}
|
}
|
||||||
if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
|
if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
|
||||||
@ -903,7 +903,7 @@ app.classes.addressbook = AppJS.extend(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get title in order to set it as document title
|
* Get title in order to set it as document title
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
@ -253,8 +253,12 @@ class IcalIterator extends Horde_Icalendar implements \Iterator
|
|||||||
return;
|
return;
|
||||||
//return PEAR::raiseError("Unable to create object for type $type");
|
//return PEAR::raiseError("Unable to create object for type $type");
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__."() about to call parsevCalendar('".substr($data,0,100)."...','$type','$this->charset')");
|
if ($this->charset && $this->charset != 'utf-8')
|
||||||
$this->component->parsevCalendar($data, $type, $this->charset);
|
{
|
||||||
|
$data = Api\Translation::convert($data, $this->charset, 'utf-8');
|
||||||
|
}
|
||||||
|
//error_log(__METHOD__."() about to call parsevCalendar('".substr($data,0,100)."...','$type')");
|
||||||
|
$this->component->parsevCalendar($data, $type);
|
||||||
|
|
||||||
// VTIMEZONE components are NOT returned, they are only processed internally
|
// VTIMEZONE components are NOT returned, they are only processed internally
|
||||||
if ($type == 'VTIMEZONE')
|
if ($type == 'VTIMEZONE')
|
||||||
|
@ -5708,11 +5708,10 @@ class Mail
|
|||||||
if ($part && ($partDisposition=='attachment' || $partDisposition=='inline' || ($part->getPrimaryType() == 'text' && $part->getSubType() == 'calendar')))
|
if ($part && ($partDisposition=='attachment' || $partDisposition=='inline' || ($part->getPrimaryType() == 'text' && $part->getSubType() == 'calendar')))
|
||||||
{
|
{
|
||||||
//$headerObject=$part->getAllDispositionParameters();//not used anywhere around here
|
//$headerObject=$part->getAllDispositionParameters();//not used anywhere around here
|
||||||
$structure_bytes = $part->getBytes();
|
$structure_mime = $part->getType();
|
||||||
$structure_mime=$part->getType();
|
$filename = $part->getName();
|
||||||
$structure_partID=$part->getMimeId();
|
$charset = $part->getContentTypeParameter('charset');
|
||||||
$filename=$part->getName();
|
//$structure_bytes = $part->getBytes(); $structure_partID=$part->getMimeId(); error_log(__METHOD__.__LINE__." fetchPartContents(".array2string($_uid).", $structure_partID, $_stream, $_preserveSeen,$structure_mime)" );
|
||||||
//error_log(__METHOD__.__LINE__." fetchPartContents(".array2string($_uid).", $structure_partID, $_stream, $_preserveSeen,$structure_mime)" );
|
|
||||||
$this->fetchPartContents($_uid, $part, $_stream, $_preserveSeen=true,$structure_mime);
|
$this->fetchPartContents($_uid, $part, $_stream, $_preserveSeen=true,$structure_mime);
|
||||||
if ($_returnPart) return $part;
|
if ($_returnPart) return $part;
|
||||||
}
|
}
|
||||||
@ -5727,8 +5726,8 @@ class Mail
|
|||||||
}
|
}
|
||||||
$attachmentData = array(
|
$attachmentData = array(
|
||||||
'type' => $structure_mime,
|
'type' => $structure_mime,
|
||||||
|
'charset' => $charset,
|
||||||
'filename' => $filename,
|
'filename' => $filename,
|
||||||
//'attachment' => $part->getContents(array('stream'=>$_stream))
|
|
||||||
'attachment' => $part->getContents(array(
|
'attachment' => $part->getContents(array(
|
||||||
// tnef_decode needs strings not a stream
|
// tnef_decode needs strings not a stream
|
||||||
'stream' => $_stream && !($filename == 'winmail.dat' && $_winmail_nr)
|
'stream' => $_stream && !($filename == 'winmail.dat' && $_winmail_nr)
|
||||||
|
@ -321,19 +321,18 @@ class Mailer extends Horde_Mime_Mail
|
|||||||
* "text/calendar; method=..." get automatic detected and added as highest priority alternative
|
* "text/calendar; method=..." get automatic detected and added as highest priority alternative
|
||||||
*
|
*
|
||||||
* @param string|resource $data Path to the attachment or open file-descriptor
|
* @param string|resource $data Path to the attachment or open file-descriptor
|
||||||
* @param string $name The file name to use for the attachment.
|
* @param string $name =null file name to use for the attachment
|
||||||
* @param string $type The content type of the file.
|
* @param string $type =null content type of the file, incl. parameters eg. "text/plain; charset=utf-8"
|
||||||
* @param string $charset The character set of the part, only relevant for text parts.
|
* @param string $old_type =null used to support phpMailer signature (deprecated)
|
||||||
* @return integer part-number
|
* @return integer part-number
|
||||||
* @throws Exception\NotFound if $file could not be opened for reading
|
* @throws Exception\NotFound if $file could not be opened for reading
|
||||||
*/
|
*/
|
||||||
public function addAttachment($data, $name = null, $type = null, $charset = 'us-ascii')
|
public function addAttachment($data, $name = null, $type = null, $old_type=null)
|
||||||
{
|
{
|
||||||
// deprecated PHPMailer::AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') call
|
// deprecated PHPMailer::AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') call
|
||||||
if ($type === 'base64')
|
if ($type === 'base64')
|
||||||
{
|
{
|
||||||
$type = $charset;
|
$type = $old_type;
|
||||||
$charset = 'us-ascii';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass file as resource to Horde_Mime_Part::setContent()
|
// pass file as resource to Horde_Mime_Part::setContent()
|
||||||
@ -358,6 +357,14 @@ class Mailer extends Horde_Mime_Mail
|
|||||||
|
|
||||||
$part = new Horde_Mime_Part();
|
$part = new Horde_Mime_Part();
|
||||||
$part->setType($type);
|
$part->setType($type);
|
||||||
|
// set content-type parameters, which get ignored by setType
|
||||||
|
if (preg_match_all('/;\s*([^=]+)=([^;]*)/', $type, $matches))
|
||||||
|
{
|
||||||
|
foreach($matches[1] as $n => $label)
|
||||||
|
{
|
||||||
|
$part->setContentTypeParameter($label, $matches[2][$n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
$part->setContents($resource);
|
$part->setContents($resource);
|
||||||
|
|
||||||
// setting name, also sets content-disposition attachment (!), therefore we have to do it after "text/calendar; method=" handling
|
// setting name, also sets content-disposition attachment (!), therefore we have to do it after "text/calendar; method=" handling
|
||||||
@ -365,7 +372,7 @@ class Mailer extends Horde_Mime_Mail
|
|||||||
|
|
||||||
// this should not be necessary, because binary data get detected by mime-type,
|
// this should not be necessary, because binary data get detected by mime-type,
|
||||||
// but at least Cyrus complains about NUL characters
|
// but at least Cyrus complains about NUL characters
|
||||||
$part->setTransferEncoding('base64', array('send' => true));
|
if (substr($type, 0, 5) != 'text/') $part->setTransferEncoding('base64', array('send' => true));
|
||||||
$part->setDisposition('attachment');
|
$part->setDisposition('attachment');
|
||||||
|
|
||||||
return $this->addMimePart($part);
|
return $this->addMimePart($part);
|
||||||
|
@ -2264,7 +2264,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
$events = array();
|
$events = array();
|
||||||
$vcal = new Horde_Icalendar;
|
$vcal = new Horde_Icalendar;
|
||||||
if (!$vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset))
|
if ($charset && $charset != 'utf-8')
|
||||||
|
{
|
||||||
|
$_vcalData = Api\Translation::convert($_vcalData, $charset, 'utf-8');
|
||||||
|
}
|
||||||
|
if (!$vcal->parsevCalendar($_vcalData, 'VCALENDAR'))
|
||||||
{
|
{
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
|
@ -405,7 +405,7 @@ class infolog_ical extends infolog_bo
|
|||||||
foreach((array)$value as $compvData)
|
foreach((array)$value as $compvData)
|
||||||
{
|
{
|
||||||
$comp = Horde_Icalendar::newComponent(substr($name,3), $vevent);
|
$comp = Horde_Icalendar::newComponent(substr($name,3), $vevent);
|
||||||
$comp->parsevCalendar($compvData,substr($name,3),'utf-8');
|
$comp->parsevCalendar($compvData,substr($name,3));
|
||||||
$vevent->addComponent($comp);
|
$vevent->addComponent($comp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -654,7 +654,11 @@ class infolog_ical extends infolog_bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
$vcal = new Horde_Icalendar;
|
$vcal = new Horde_Icalendar;
|
||||||
if (!($vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset)))
|
if ($charset && $charset != 'utf-8')
|
||||||
|
{
|
||||||
|
$_vcalData = Api\Translation::convert($_vcalData, $charset, 'utf-8');
|
||||||
|
}
|
||||||
|
if (!($vcal->parsevCalendar($_vcalData, 'VCALENDAR')))
|
||||||
{
|
{
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
@ -1096,7 +1100,11 @@ class infolog_ical extends infolog_bo
|
|||||||
|
|
||||||
case 'text/x-vnote':
|
case 'text/x-vnote':
|
||||||
$vnote = new Horde_Icalendar;
|
$vnote = new Horde_Icalendar;
|
||||||
if (!$vnote->parsevCalendar($_data, 'VCALENDAR', $charset)) return false;
|
if ($charset && $charset != 'utf-8')
|
||||||
|
{
|
||||||
|
$_data = Api\Translation::convert($_data, $charset, 'utf-8');
|
||||||
|
}
|
||||||
|
if (!$vnote->parsevCalendar($_data, 'VCALENDAR')) return false;
|
||||||
|
|
||||||
$components = $vnote->getComponent();
|
$components = $vnote->getComponent();
|
||||||
foreach ($components as $component)
|
foreach ($components as $component)
|
||||||
|
@ -913,6 +913,11 @@ class mail_compose
|
|||||||
{
|
{
|
||||||
$name .= '.'.mime_magic::mime2ext($type);
|
$name .= '.'.mime_magic::mime2ext($type);
|
||||||
}
|
}
|
||||||
|
// use type specified by caller, if Vfs reports only default, or contains specified type (eg. "text/vcard; charset=utf-8")
|
||||||
|
if (!empty($types[$k]) && ($type == 'application/octet-stream' || stripos($types[$k], $type) === 0))
|
||||||
|
{
|
||||||
|
$type = $types[$k];
|
||||||
|
}
|
||||||
$path = str_replace('+','%2B',$path);
|
$path = str_replace('+','%2B',$path);
|
||||||
$formData = array(
|
$formData = array(
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
|
@ -2383,7 +2383,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
|||||||
$eventid = $calendar_ical->search($attachment['attachment'],-1);
|
$eventid = $calendar_ical->search($attachment['attachment'],-1);
|
||||||
//error_log(__METHOD__.array2string($eventid));
|
//error_log(__METHOD__.array2string($eventid));
|
||||||
if (!$eventid) $eventid = -1;
|
if (!$eventid) $eventid = -1;
|
||||||
$event = $calendar_ical->importVCal($attachment['attachment'],(is_array($eventid)?$eventid[0]:$eventid),null,true);
|
$event = $calendar_ical->importVCal($attachment['attachment'],(is_array($eventid)?$eventid[0]:$eventid),null,true,0,'',null,$attachment['charset']);
|
||||||
//error_log(__METHOD__.$event);
|
//error_log(__METHOD__.$event);
|
||||||
if ((int)$event > 0)
|
if ((int)$event > 0)
|
||||||
{
|
{
|
||||||
@ -2401,7 +2401,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
|||||||
// double \r\r\n seems to end a vcard prematurely, so we set them to \r\n
|
// double \r\r\n seems to end a vcard prematurely, so we set them to \r\n
|
||||||
//error_log(__METHOD__.__LINE__.$attachment['attachment']);
|
//error_log(__METHOD__.__LINE__.$attachment['attachment']);
|
||||||
$attachment['attachment'] = str_replace("\r\r\n", "\r\n", $attachment['attachment']);
|
$attachment['attachment'] = str_replace("\r\r\n", "\r\n", $attachment['attachment']);
|
||||||
$vcard = $addressbook_vcal->vcardtoegw($attachment['attachment']);
|
$vcard = $addressbook_vcal->vcardtoegw($attachment['attachment'], $attachment['charset']);
|
||||||
if ($vcard['uid'])
|
if ($vcard['uid'])
|
||||||
{
|
{
|
||||||
$vcard['uid'] = trim($vcard['uid']);
|
$vcard['uid'] = trim($vcard['uid']);
|
||||||
@ -2412,7 +2412,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
|||||||
// if there are not enough fields in the vcard (or the parser was unable to correctly parse the vcard (as of VERSION:3.0 created by MSO))
|
// if there are not enough fields in the vcard (or the parser was unable to correctly parse the vcard (as of VERSION:3.0 created by MSO))
|
||||||
if ($contact || count($vcard)>2)
|
if ($contact || count($vcard)>2)
|
||||||
{
|
{
|
||||||
$contact = $addressbook_vcal->addVCard($attachment['attachment'],(is_array($contact)?array_shift($contact):$contact),true);
|
$contact = $addressbook_vcal->addVCard($attachment['attachment'],(is_array($contact)?array_shift($contact):$contact),true,$attachment['charset']);
|
||||||
}
|
}
|
||||||
if ((int)$contact > 0)
|
if ((int)$contact > 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user