mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-21 23:43:17 +01:00
merge changes from update-zpush-2.3 branch into master
This commit is contained in:
commit
6a02f1c19a
@ -536,6 +536,7 @@ class Accounts
|
||||
$underscore = '_';
|
||||
}
|
||||
if (!$domain) $domain = $GLOBALS['egw_info']['server']['mail_suffix'];
|
||||
if (!$domain) $domain = $_SERVER['SERVER_NAME'];
|
||||
|
||||
$email = str_replace(array('first','last','initial','account','dot','underscore','-'),
|
||||
array($first,$last,substr($first,0,1),$account,$dot,$underscore,''),
|
||||
@ -736,9 +737,10 @@ class Accounts
|
||||
*
|
||||
* @param int|string $account_id numeric account_id or account_lid
|
||||
* @param string $which ='account_lid' type to convert to: account_lid (default), account_email, ...
|
||||
* @param boolean $generate_email =false true: generate an email address, if user has none
|
||||
* @return string|boolean converted value or false on error ($account_id not found)
|
||||
*/
|
||||
static function id2name($account_id, $which='account_lid')
|
||||
static function id2name($account_id, $which='account_lid', $generate_email=false)
|
||||
{
|
||||
if (!is_numeric($account_id) && !($account_id = self::getInstance()->name2id($account_id)))
|
||||
{
|
||||
@ -751,6 +753,10 @@ class Accounts
|
||||
unset($e);
|
||||
return false;
|
||||
}
|
||||
if ($generate_email && $which === 'account_email' && empty($data[$which]))
|
||||
{
|
||||
return self::email($data['account_firstname'], $data['account_lastname'], $data['account_lid']);
|
||||
}
|
||||
return $data[$which];
|
||||
}
|
||||
|
||||
|
159
api/src/Db/Pdo.php
Normal file
159
api/src/Db/Pdo.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware API: PDO database connection
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @subpackage db
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2008-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace EGroupware\Api\Db;
|
||||
|
||||
/**
|
||||
* PDO database connection
|
||||
*/
|
||||
class Pdo
|
||||
{
|
||||
/**
|
||||
* Reference to the PDO object we use
|
||||
*
|
||||
* @var \PDO
|
||||
*/
|
||||
static protected $pdo;
|
||||
|
||||
/**
|
||||
* PDO database type: mysql, pgsl
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $pdo_type;
|
||||
|
||||
/**
|
||||
* Case sensitive comparison operator, for mysql we use ' COLLATE utf8_bin ='
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $case_sensitive_equal = '=';
|
||||
|
||||
/**
|
||||
* Get active PDO connection
|
||||
*
|
||||
* @return \PDO
|
||||
* @throws \PDOException when opening PDO connection fails
|
||||
* @throws Exception when opening regular db-connection fails
|
||||
*/
|
||||
static public function connection()
|
||||
{
|
||||
if (!isset(self::$pdo))
|
||||
{
|
||||
self::reconnect();
|
||||
}
|
||||
return self::$pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconnect to database
|
||||
*/
|
||||
static public function reconnect()
|
||||
{
|
||||
self::$pdo = self::_pdo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pdo object / connection, as long as pdo is not generally used in eGW
|
||||
*
|
||||
* @return \PDO
|
||||
*/
|
||||
static protected function _pdo()
|
||||
{
|
||||
$egw_db = isset($GLOBALS['egw_setup']) ? $GLOBALS['egw_setup']->db : $GLOBALS['egw']->db;
|
||||
|
||||
switch($egw_db->Type)
|
||||
{
|
||||
case 'mysqli':
|
||||
case 'mysqlt':
|
||||
case 'mysql':
|
||||
self::$case_sensitive_equal = '= BINARY ';
|
||||
self::$pdo_type = 'mysql';
|
||||
break;
|
||||
default:
|
||||
self::$pdo_type = $egw_db->Type;
|
||||
break;
|
||||
}
|
||||
// get host used be egw_db
|
||||
$egw_db->connect();
|
||||
$host = $egw_db->get_host();
|
||||
|
||||
$dsn = self::$pdo_type.':dbname='.$egw_db->Database.($host ? ';host='.$host.($egw_db->Port ? ';port='.$egw_db->Port : '') : '');
|
||||
// check once if pdo extension and DB specific driver is loaded or can be loaded
|
||||
static $pdo_available=null;
|
||||
if (is_null($pdo_available))
|
||||
{
|
||||
foreach(array('pdo','pdo_'.self::$pdo_type) as $ext)
|
||||
{
|
||||
check_load_extension($ext,true); // true = throw Exception
|
||||
}
|
||||
$pdo_available = true;
|
||||
}
|
||||
// set client charset of the connection
|
||||
switch(self::$pdo_type)
|
||||
{
|
||||
case 'mysql':
|
||||
$dsn .= ';charset=utf8';
|
||||
break;
|
||||
case 'pgsql':
|
||||
$query = "SET NAMES 'utf-8'";
|
||||
break;
|
||||
}
|
||||
try {
|
||||
self::$pdo = new \PDO($dsn,$egw_db->User,$egw_db->Password,array(
|
||||
\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION,
|
||||
));
|
||||
}
|
||||
catch(\PDOException $e)
|
||||
{
|
||||
unset($e);
|
||||
// Exception reveals password, so we ignore the exception and connect again without pw, to get the right exception without pw
|
||||
self::$pdo = new \PDO($dsn,$egw_db->User,'$egw_db->Password');
|
||||
}
|
||||
if ($query)
|
||||
{
|
||||
self::$pdo->exec($query);
|
||||
}
|
||||
return self::$pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just a little abstration 'til I know how to organise stuff like that with PDO
|
||||
*
|
||||
* @param mixed $time
|
||||
* @return string Y-m-d H:i:s
|
||||
*/
|
||||
static public function _pdo_timestamp($time)
|
||||
{
|
||||
if (is_numeric($time))
|
||||
{
|
||||
$time = date('Y-m-d H:i:s',$time);
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just a little abstration 'til I know how to organise stuff like that with PDO
|
||||
*
|
||||
* @param boolean $val
|
||||
* @return string '1' or '0' for mysql, 'true' or 'false' for everyone else
|
||||
*/
|
||||
static public function _pdo_boolean($val)
|
||||
{
|
||||
if (self::$pdo_type == 'mysql')
|
||||
{
|
||||
return $val ? '1' : '0';
|
||||
}
|
||||
return $val ? 'true' : 'false';
|
||||
}
|
||||
}
|
@ -283,7 +283,7 @@ class Mail
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(__METHOD__." failed to load the Profile for ProfileID for $_profileID with error:".$e->getMessage().($e->details?', '.$e->details:''));
|
||||
throw new Exception(__METHOD__." failed to load the Profile for ProfileID for $_profileID with error:".$e->getMessage().($e->details?', '.$e->details:''));
|
||||
}
|
||||
}
|
||||
self::storeActiveProfileIDToPref(self::$instances[$_profileID]->icServer, $_profileID, $_validate );
|
||||
|
@ -34,7 +34,7 @@ use EGroupware\Api;
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.stream-wrapper-register.php
|
||||
*/
|
||||
class StreamWrapper implements Vfs\StreamWrapperIface
|
||||
class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
||||
{
|
||||
/**
|
||||
* Mime type of directories, the old vfs uses 'Directory', while eg. WebDAV uses 'httpd/unix-directory'
|
||||
@ -141,12 +141,6 @@ class StreamWrapper implements Vfs\StreamWrapperIface
|
||||
* @var array $path => info-array pairs
|
||||
*/
|
||||
static protected $stat_cache = array();
|
||||
/**
|
||||
* Reference to the PDO object we use
|
||||
*
|
||||
* @var \PDO
|
||||
*/
|
||||
static protected $pdo;
|
||||
/**
|
||||
* Array with filenames of dir opened with dir_opendir
|
||||
*
|
||||
@ -1624,116 +1618,6 @@ class StreamWrapper implements Vfs\StreamWrapperIface
|
||||
return $stat;
|
||||
}
|
||||
|
||||
public static $pdo_type;
|
||||
/**
|
||||
* Case sensitive comparison operator, for mysql we use ' COLLATE utf8_bin ='
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $case_sensitive_equal = '=';
|
||||
|
||||
/**
|
||||
* Reconnect to database
|
||||
*/
|
||||
static public function reconnect()
|
||||
{
|
||||
self::$pdo = self::_pdo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pdo object / connection, as long as pdo is not generally used in eGW
|
||||
*
|
||||
* @return \PDO
|
||||
*/
|
||||
static protected function _pdo()
|
||||
{
|
||||
$egw_db = isset($GLOBALS['egw_setup']) ? $GLOBALS['egw_setup']->db : $GLOBALS['egw']->db;
|
||||
|
||||
switch($egw_db->Type)
|
||||
{
|
||||
case 'mysqli':
|
||||
case 'mysqlt':
|
||||
case 'mysql':
|
||||
self::$case_sensitive_equal = '= BINARY ';
|
||||
self::$pdo_type = 'mysql';
|
||||
break;
|
||||
default:
|
||||
self::$pdo_type = $egw_db->Type;
|
||||
break;
|
||||
}
|
||||
// get host used be egw_db
|
||||
$egw_db->connect();
|
||||
$host = $egw_db->get_host();
|
||||
|
||||
$dsn = self::$pdo_type.':dbname='.$egw_db->Database.($host ? ';host='.$host.($egw_db->Port ? ';port='.$egw_db->Port : '') : '');
|
||||
// check once if pdo extension and DB specific driver is loaded or can be loaded
|
||||
static $pdo_available=null;
|
||||
if (is_null($pdo_available))
|
||||
{
|
||||
foreach(array('pdo','pdo_'.self::$pdo_type) as $ext)
|
||||
{
|
||||
check_load_extension($ext,true); // true = throw Exception
|
||||
}
|
||||
$pdo_available = true;
|
||||
}
|
||||
// set client charset of the connection
|
||||
switch(self::$pdo_type)
|
||||
{
|
||||
case 'mysql':
|
||||
$dsn .= ';charset=utf8';
|
||||
break;
|
||||
case 'pgsql':
|
||||
$query = "SET NAMES 'utf-8'";
|
||||
break;
|
||||
}
|
||||
try {
|
||||
self::$pdo = new \PDO($dsn,$egw_db->User,$egw_db->Password,array(
|
||||
\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION,
|
||||
));
|
||||
}
|
||||
catch(\PDOException $e)
|
||||
{
|
||||
unset($e);
|
||||
// Exception reveals password, so we ignore the exception and connect again without pw, to get the right exception without pw
|
||||
self::$pdo = new \PDO($dsn,$egw_db->User,'$egw_db->Password');
|
||||
}
|
||||
if ($query)
|
||||
{
|
||||
self::$pdo->exec($query);
|
||||
}
|
||||
return self::$pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just a little abstration 'til I know how to organise stuff like that with PDO
|
||||
*
|
||||
* @param mixed $time
|
||||
* @return string Y-m-d H:i:s
|
||||
*/
|
||||
static protected function _pdo_timestamp($time)
|
||||
{
|
||||
if (is_numeric($time))
|
||||
{
|
||||
$time = date('Y-m-d H:i:s',$time);
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just a little abstration 'til I know how to organise stuff like that with PDO
|
||||
*
|
||||
* @param boolean $val
|
||||
* @return string '1' or '0' for mysql, 'true' or 'false' for everyone else
|
||||
*/
|
||||
static protected function _pdo_boolean($val)
|
||||
{
|
||||
if (self::$pdo_type == 'mysql')
|
||||
{
|
||||
return $val ? '1' : '0';
|
||||
}
|
||||
return $val ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum value for a single hash element (should be 10^N): 10, 100 (default), 1000, ...
|
||||
*
|
||||
|
@ -1078,10 +1078,9 @@ class calendar_zpush implements activesync_plugin_write, activesync_plugin_meeti
|
||||
$this->backend->note2messagenote($event['description'], $bodypreference, $message->asbody);
|
||||
}
|
||||
}
|
||||
$message->md5body = md5($event['description']);
|
||||
|
||||
$message->organizername = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_fullname');
|
||||
$message->organizeremail = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_email');
|
||||
// at least iOS calendar crashes, if organizer has no email address (true = generate an email, if user has none)
|
||||
$message->organizeremail = $GLOBALS['egw']->accounts->id2name($event['owner'], 'account_email', true);
|
||||
|
||||
$message->sensitivity = $event['public'] ? 0 : 2; // 0=normal, 1=personal, 2=private, 3=confidential
|
||||
|
||||
@ -1102,7 +1101,7 @@ class calendar_zpush implements activesync_plugin_write, activesync_plugin_meeti
|
||||
if (is_numeric($uid))
|
||||
{
|
||||
$attendee->name = $GLOBALS['egw']->accounts->id2name($uid,'account_fullname');
|
||||
$attendee->email = $GLOBALS['egw']->accounts->id2name($uid,'account_email');
|
||||
$attendee->email = $GLOBALS['egw']->accounts->id2name($uid, 'account_email', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1113,7 +1112,7 @@ class calendar_zpush implements activesync_plugin_write, activesync_plugin_meeti
|
||||
|
||||
if (!$info['email'] && $info['responsible'])
|
||||
{
|
||||
$info['email'] = $GLOBALS['egw']->accounts->id2name($info['responsible'],'account_email');
|
||||
$info['email'] = $GLOBALS['egw']->accounts->id2name($info['responsible'], 'account_email', true);
|
||||
}
|
||||
$attendee->name = empty($info['cn']) ? $info['name'] : $info['cn'];
|
||||
$attendee->email = $info['email'];
|
||||
|
@ -410,7 +410,12 @@ class infolog_zpush implements activesync_plugin_write
|
||||
switch ($attr)
|
||||
{
|
||||
case 'info_des':
|
||||
$infolog[$attr] = $this->backend->messagenote2note($message->body, $message->rtf, $message->airsyncbasebody);
|
||||
// only change info_des, if one given, as iOS5 skips description in ChangeMessage
|
||||
// --> we ignore empty / not set description, so description get no longer lost, but you cant empty it via eSync
|
||||
if (($description = $this->backend->messagenote2note($message->body, $message->rtf, $message->asbody)))
|
||||
{
|
||||
$infolog[$attr] = $description;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'info_cat':
|
||||
|
@ -172,6 +172,22 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
'default' => 'sendifnocalnotif',
|
||||
'admin' => False,
|
||||
);
|
||||
/*
|
||||
$settings['mail-useSignature'] = array(
|
||||
'type' => 'select',
|
||||
'label' => 'control if and which available signature is added to outgoing mails',
|
||||
'name' => 'mail-useSignature',
|
||||
'help' => 'control the use of signatures',
|
||||
'values' => array(
|
||||
'sendifnocalnotif'=>'only send if there is no notification in calendar',
|
||||
'send'=>'yes, always add EGroupware signatures to outgoing mails',
|
||||
'nosend'=>'no, never add EGroupware signatures to outgoing mails',
|
||||
),
|
||||
'xmlrpc' => True,
|
||||
'default' => 'nosend',
|
||||
'admin' => False,
|
||||
);
|
||||
*/
|
||||
return $settings;
|
||||
}
|
||||
|
||||
@ -369,8 +385,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
// Horde SMTP Class uses utf-8 by default. as we set charset always to utf-8
|
||||
$mailObject->Sender = $activeMailProfile['ident_email'];
|
||||
$mailObject->From = $activeMailProfile['ident_email'];
|
||||
$mailObject->FromName = $mailObject->EncodeHeader(Mail::generateIdentityString($activeMailProfile,false));
|
||||
$mailObject->AddCustomHeader('X-Mailer: mail-Activesync');
|
||||
$mailObject->FromName = Mail::generateIdentityString($activeMailProfile,false);
|
||||
$mailObject->addHeader('X-Mailer', 'mail-Activesync');
|
||||
|
||||
|
||||
// prepare addressee list; moved the adding of addresses to the mailobject down
|
||||
@ -665,7 +681,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
if ($this->debugLevel>0) ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' Key:'.$key.'->'.array2string($attachment));
|
||||
$attachmentNames .= $attachment['name']."\n";
|
||||
$attachmentData = $this->mail->getAttachment($uid, $attachment['partID'],0,false,false,$folder);
|
||||
/*$x =*/ $mailObject->AddStringAttachment($attachmentData['attachment'], $mailObject->EncodeHeader($attachment['name']), $attachment['mimeType']);
|
||||
/*$x =*/ $mailObject->AddStringAttachment($attachmentData['attachment'], $attachment['name'], $attachment['mimeType']);
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' added part with number:'.$x);
|
||||
}
|
||||
}
|
||||
@ -939,9 +955,12 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__." bodypreference 4 requested");
|
||||
$output->asbody->type = SYNC_BODYPREFERENCE_MIME;//4;
|
||||
// use Api\Mailer::convert to convert charset of all text parts to utf-8, which is a z-push or AS requirement!
|
||||
// ToDo: check if above is true for mime-message, otherwise with could use a stream without conversion
|
||||
$Body = Api\Mailer::convert($this->mail->getMessageRawBody($id, '', $_folderName));
|
||||
if ($this->debugLevel>2) ZLog::Write(LOGLEVEL_DEBUG, __METHOD__.__LINE__." Setting Mailobjectcontent to output:".$Body);
|
||||
$output->asbody->data = $Body;
|
||||
if ((string)$Body === '') $Body = ' ';
|
||||
$output->asbody->data = StringStreamWrapper::Open($Body);
|
||||
$output->asbody->estimatedDataSize = strlen($Body);
|
||||
}
|
||||
else if ($bpReturnType==2) //SYNC_BODYPREFERENCE_HTML
|
||||
{
|
||||
@ -975,7 +994,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
}
|
||||
// output->nativebodytype is used as marker that the original message was of type ... but is now converted to, as type 2 is requested.
|
||||
$output->nativebodytype = 2;
|
||||
$output->asbody->data = $htmlbody;
|
||||
$output->asbody->data = StringStreamWrapper::Open($htmlbody);
|
||||
$output->asbody->estimatedDataSize = strlen($htmlbody);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -996,16 +1016,16 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
$plainBody = Utils::Utf8_truncate($plainBody, $truncsize);
|
||||
$output->asbody->truncated = 1;
|
||||
}
|
||||
$output->asbody->data = $plainBody;
|
||||
$output->asbody->data = StringStreamWrapper::Open((string)$plainBody !== '' ? $plainBody : ' ');
|
||||
$output->asbody->estimatedDataSize = strlen($plainBody);
|
||||
}
|
||||
// In case we have nothing for the body, send at least a blank...
|
||||
// dw2412 but only in case the body is not rtf!
|
||||
if ($output->asbody->type != 3 && (!isset($output->asbody->data) || strlen($output->asbody->data) == 0))
|
||||
if ($output->asbody->type != 3 && !isset($output->asbody->data))
|
||||
{
|
||||
$output->asbody->data = " ";
|
||||
$output->asbody->data = StringStreamWrapper::Open(" ");
|
||||
$output->asbody->estimatedDataSize = 1;
|
||||
}
|
||||
// determine estimated datasize for all the above cases ...
|
||||
$output->asbody->estimatedDataSize = strlen($output->asbody->data);
|
||||
}
|
||||
// end AS12 Stuff
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' gather Header info:'.$headers['SUBJECT'].' from:'.$headers['DATE']);
|
||||
@ -1186,29 +1206,11 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
*
|
||||
* @param string $fid - id
|
||||
* @param string $attname - should contain (folder)id
|
||||
* @return true, prints the content of the attachment
|
||||
* @return SyncItemOperationsAttachment-object
|
||||
*/
|
||||
function GetAttachmentData($fid,$attname) {
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname')".function_backtrace());
|
||||
//error_log(__METHOD__.__LINE__." Fid: $fid (attname: '$attname')");
|
||||
list($folderid, $id, $part) = explode(":", $attname);
|
||||
|
||||
$this->splitID($folderid, $account, $folder);
|
||||
|
||||
if (!isset($this->mail)) $this->mail = Mail::getInstance(false,self::$profileID,true,false,true);
|
||||
|
||||
$this->mail->reopen($folder);
|
||||
$attachment = $this->mail->getAttachment($id,$part,0,false,true,$folder);
|
||||
$SIOattachment = new SyncItemOperationsAttachment();
|
||||
fseek($attachment['attachment'], 0, SEEK_SET); // z-push requires stream seeked to start
|
||||
$SIOattachment->data = $attachment['attachment'];
|
||||
//ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname') Data:".$attachment['attachment']);
|
||||
if (isset($attachment['type']) )
|
||||
$SIOattachment->contenttype = $attachment['type'];
|
||||
|
||||
unset($attachment);
|
||||
|
||||
return $SIOattachment;
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname')");
|
||||
return $this->_GetAttachmentData($fid,$attname);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1222,6 +1224,21 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
* @return SyncItemOperationsAttachment-object
|
||||
*/
|
||||
function ItemOperationsGetAttachmentData($fid,$attname) {
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname')");
|
||||
return $this->_GetAttachmentData($fid,$attname);
|
||||
}
|
||||
|
||||
/**
|
||||
* _GetAttachmentData implements
|
||||
* -ItemOperationsGetAttachmentData
|
||||
* -GetAttachmentData
|
||||
*
|
||||
* @param string $fid - id
|
||||
* @param string $attname - should contain (folder)id
|
||||
* @return SyncItemOperationsAttachment-object
|
||||
*/
|
||||
private function _GetAttachmentData($fid,$attname)
|
||||
{
|
||||
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname')".function_backtrace());
|
||||
//error_log(__METHOD__.__LINE__." Fid: $fid (attname: '$attname')");
|
||||
list($folderid, $id, $part) = explode(":", $attname);
|
||||
@ -1232,15 +1249,16 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
|
||||
$this->mail->reopen($folder);
|
||||
$attachment = $this->mail->getAttachment($id,$part,0,false,true,$folder);
|
||||
$SIOattachment = new SyncItemOperationsAttachment();
|
||||
$SIOattachment = new SyncItemOperationsAttachment();
|
||||
fseek($attachment['attachment'], 0, SEEK_SET); // z-push requires stream seeked to start
|
||||
$SIOattachment->data = $attachment['attachment'];
|
||||
if (isset($attachment['type']) )
|
||||
$SIOattachment->contenttype = $attachment['type'];
|
||||
$SIOattachment->data = $attachment['attachment'];
|
||||
//ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.": $fid (attname: '$attname') Data:".$attachment['attachment']);
|
||||
if (isset($attachment['type']) )
|
||||
$SIOattachment->contenttype = $attachment['type'];
|
||||
|
||||
unset($attachment);
|
||||
|
||||
return $SIOattachment;
|
||||
return $SIOattachment;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1966,37 +1984,73 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
|
||||
|
||||
private $folderHashes;
|
||||
|
||||
/**
|
||||
* Statemaschine instance used to store folders
|
||||
*
|
||||
* @var activesync_statemaschine
|
||||
*/
|
||||
private $fh_state_maschine;
|
||||
|
||||
/**
|
||||
* state_type (and _key) used to store folder hashes
|
||||
*/
|
||||
const FOLDER_STATE_TYPE = 'folder_hashes';
|
||||
|
||||
/**
|
||||
* Read hashfile from state dir
|
||||
*/
|
||||
private function readFolderHashes()
|
||||
{
|
||||
if ((file_exists($file = $this->hashFile()) || file_exists($file = $this->hashFile(true))) &&
|
||||
($hashes = file_get_contents($file)))
|
||||
if (!isset($this->fh_state_maschine))
|
||||
{
|
||||
$this->folderHashes = json_decode($hashes,true);
|
||||
// fallback in case hashes have been serialized instead of being json-encoded
|
||||
if (json_last_error()!=JSON_ERROR_NONE)
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__." error decoding with json");
|
||||
$this->folderHashes = unserialize($hashes);
|
||||
}
|
||||
$this->fh_state_maschine = new activesync_statemachine($this->backend);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->folderHashes = array();
|
||||
try {
|
||||
$this->folderHashes = $this->fh_state_maschine->getState(Request::GetDeviceID(),
|
||||
self::FOLDER_STATE_TYPE, self::FOLDER_STATE_TYPE, 0);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
unset($e);
|
||||
if ((file_exists($file = $this->hashFile()) || file_exists($file = $this->hashFile(true))) &&
|
||||
($hashes = file_get_contents($file)))
|
||||
{
|
||||
$this->folderHashes = json_decode($hashes,true);
|
||||
// fallback in case hashes have been serialized instead of being json-encoded
|
||||
if (json_last_error()!=JSON_ERROR_NONE)
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__." error decoding with json");
|
||||
$this->folderHashes = unserialize($hashes);
|
||||
}
|
||||
// store folder-hashes to state
|
||||
$this->storeFolderHashes();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->folderHashes = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store hashfile in state dir
|
||||
* Store hashfile via state-maschine
|
||||
*
|
||||
* return int|boolean false on error
|
||||
*/
|
||||
private function storeFolderHashes()
|
||||
{
|
||||
// make sure $this->folderHashes is an array otherwise json_encode may fail on decode for string,integer,float or boolean
|
||||
return file_put_contents($this->hashFile(), json_encode((is_array($this->folderHashes)?$this->folderHashes:array($this->folderHashes))));
|
||||
if (!isset($this->fh_state_maschine))
|
||||
{
|
||||
$this->fh_state_maschine = new activesync_statemachine($this->backend);
|
||||
}
|
||||
try {
|
||||
$this->fh_state_maschine->setState($this->folderHashes, Request::GetDeviceID(),
|
||||
self::FOLDER_STATE_TYPE, self::FOLDER_STATE_TYPE, 0);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
_egw_log_exception($e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user