"Fossies" - the Fresh Open Source Software Archive

Member "z-push/backend/groupe.php" (2 Aug 2013, 82823 Bytes) of package /linux/www/old/group-e_z-push_v3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "groupe.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 /***********************************************
    3 * File      :   vcarddir.php
    4 * Project   :   Z-Push
    5 * Descr     :   This backend is for vcard
    6 *               directories.
    7 *
    8 * Created   :   01.10.2007
    9 *
   10 * � Zarafa Deutschland GmbH, www.zarafaserver.de
   11 * This file is distributed under GPL v2.
   12 * Consult LICENSE file for details
   13 ************************************************/
   14 include_once('diffbackend.php');
   15 include_once('mime.php');
   16 include_once('mimeDecode.php');
   17 include_once('z_RFC822.php');
   18 
   19 function setMessageBody ($message,$tmpBody,$bodypreference) {
   20     if ($bodypreference == false) {
   21             $message->body = $tmpBody;
   22             $message->bodysize = strlen($message->body);
   23             $message->bodytruncated = 0;
   24     } else {
   25         $message->airsyncbasebody = new SyncAirSyncBaseBody();
   26         debugLog("airsyncbasebody!");
   27         $message->airsyncbasenativebodytype=1;
   28         if (isset($bodypreference[2])) {
   29             debugLog("HTML Body");
   30             // Send HTML if requested and native type was html
   31             $message->airsyncbasebody->type = 2;
   32             $html='<html>';
   33             $html.='<head>';
   34             $html.='<meta name="Generator" content="Z-Push">';
   35             $html.='<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
   36             $html.='</head>';
   37             $html.='<body>';
   38             $html.=nl2br($tmpBody);
   39             $html.='</body>';
   40             $html.='</html>';
   41             if (isset($bodypreference[2]["TruncationSize"]) && strlen($html) > $bodypreference[2]["TruncationSize"]) {
   42                 $html = utf8_truncate($html,$bodypreference[2]["TruncationSize"]);
   43                 $message->airsyncbasebody->truncated = 1;
   44             }
   45             $message->airsyncbasebody->data = $html;
   46             $message->airsyncbasebody->estimateddatasize = strlen($html);
   47         } else {
   48             // Send Plaintext as Fallback or if original body is plaintext
   49             debugLog("Plaintext Body");
   50             $message->airsyncbasebody->type = 1;
   51             if(isset($bodypreference[1]["TruncationSize"]) && strlen($tmpBody) > $bodypreference[1]["TruncationSize"]) {
   52                 $plain = utf8_truncate($tmpBody, $bodypreference[1]["TruncationSize"]);
   53                 $message->airsyncbasebody->truncated = 1;
   54             }
   55             $message->airsyncbasebody->estimateddatasize = strlen($tmpBody);
   56             $message->airsyncbasebody->data = $tmpBody;
   57         }
   58         // In case we have nothing for the body, send at least a blank...
   59         // dw2412 but only in case the body is not rtf!
   60         if ($message->airsyncbasebody->type != 3 && (!isset($message->airsyncbasebody->data) || strlen($message->airsyncbasebody->data) == 0)) {
   61             $message->airsyncbasebody->data = " ";
   62             $message->airsyncbasebody->estimateddatasize = 1;
   63         }
   64     }
   65 }
   66 function convertMessageBody($message) {
   67     if (isset($message->airsyncbasebody)) {
   68         switch($message->airsyncbasebody->type) {
   69             case '3'    : $message->rtf = $message->airsyncbasebody->data; break;
   70             case '1'    : $message->body = $message->airsyncbasebody->data; break;
   71         }
   72     }
   73     if (isset($message->rtf)) {
   74         // Nokia MfE 2.9.158 sends contact notes with RTF and Body element.
   75         // The RTF is empty, the body contains the note therefore we need to unpack the rtf
   76         // to see if it is realy empty and in case not, take the appointment body.
   77         $rtf_body = new rtf ();
   78         $rtf_body->loadrtf(base64_decode($message->rtf));
   79         $rtf_body->output("ascii");
   80         $rtf_body->parse();
   81         if (isset($message->body) &&
   82             isset($rtf_body->out) &&
   83             $rtf_body->out == "" && $message->body != "") {
   84             unset($message->rtf);
   85         }
   86         debugLog('iConDir::RTFDATA:' . $message->rtf);
   87         $rtf_body = new rtf ();
   88         $rtf_body->loadrtf(base64_decode($message->rtf));
   89         $rtf_body->output("ascii");
   90         $rtf_body->parse();
   91         debugLog('iConDir::RTFDATA-parsed:' . $rtf_body->out);
   92         //put rtf into body
   93         if($rtf_body->out <> "") $message->body=$rtf_body->out;
   94     }
   95 }
   96 class GroupeContact {
   97     public $_deviceProperties;
   98     public $_syncSettings;
   99     public $_mapping = array();
  100     function __construct() {
  101         global $protocolversion;
  102         $this->_mapping=array(
  103             array("body",'Notiz'),
  104             array("fileas",'Name'),
  105             array("companyname",'Firma'),
  106             array("firstname",'Vorname'),
  107             array("lastname",'Nachname'),
  108             array("businesscity",'AOrt'),
  109             array("businesscountry",'AProv'),
  110             array("businesspostalcode",'APlz'),
  111             array("businessstate",'ALand'),
  112             array("businessstreet",'AStrasse'),
  113             array("businessfaxnumber",array('Fax',0)),
  114             array("businessphonenumber",array('ATel',0)),
  115             array("business2phonenumber",array('ATel',1)),
  116             array("categories",'Categories'),
  117             array("email1address",array('Email',0)),
  118             array("email2address",array('Email',1)),
  119             array("email3address",array('Email',2)),
  120             array("homephonenumber",array('PTel',0)),
  121             array("home2phonenumber",array('PTel',1)),
  122             array("homecity",'POrt'),
  123             array("homecountry",'PProv'),
  124             array("homepostalcode",'PPlz'),
  125             array("homestate",'PLand'),
  126             array("homestreet",'PStrasse'),
  127             array("homefaxnumber",array('Fax',1)),
  128             array("jobtitle",'Beruf'),
  129             array("title",'Titel'),
  130             //array("middlename",''),
  131             array("mobilephonenumber",array('Mobil',0)),
  132             array("radiophonenumber",array('Mobil',1)),
  133             array("pagernumber",array('Intern',0)),
  134             array("carphonenumber",array('Andere',0)),
  135             array("webpage",array('Url',0)),
  136         );
  137         if(isset($protocolversion) && $protocolversion >= 2.5) {
  138             $this->_mapping+= array(
  139                 array("imaddress",'Iptel'),
  140                 array("governmentid",'Iva'),
  141                 array("customerid",'Mwst'),
  142                 array("nickname",'Nickname'),
  143             );
  144         }
  145    }
  146    function setDeviceProperties($val) {
  147     $this->_deviceProperties=$val;
  148    }
  149    function setSyncSettings($val) {
  150     $this->_syncSettings=$val;
  151    }
  152    function groupe2message($groupe, $truncsize,$bodypreference=false,$optionbodypreference=false, $mimesupport=0) {
  153         debugLog('groupe2contact');
  154         $message=new SyncContact();
  155         foreach ($this->_mapping as $val) {
  156             $msgKey=$val[0];$grpKey=$val[1];
  157             switch($msgKey) {
  158                 case 'body':
  159                     setMessageBody($message,isset($groupe->$grpKey)?$groupe->$grpKey:'',$bodypreference);
  160                 break;
  161                 default:
  162                     if (is_array($grpKey)) {
  163                         if (isset($groupe->{$grpKey[0]})) {
  164                             $tmpData=explode('||',$groupe->{$grpKey[0]});
  165                             $message->$msgKey=isset($tmpData[$grpKey[1]])?$tmpData[$grpKey[1]]:'';
  166                         }
  167                     } else {
  168                         if (isset($groupe->$grpKey)) {
  169                             $message->$msgKey=$groupe->$grpKey;
  170                         }
  171                     }
  172                 break;
  173             }
  174         }
  175         //debugLog(print_r($message,1));
  176         return $message;
  177     }
  178     function message2groupe($message,$groupe) {
  179         debugLog('contact2groupe');
  180         //$message=(array)$message;
  181         //debugLog(print_r($message,1));
  182         //debugLog(print_r($groupe,1));
  183         convertMessageBody($message);
  184 
  185         foreach ($this->_mapping as $val) {
  186             $msgKey=$val[0];$grpKey=$val[1];
  187             switch($msgKey) {
  188                 case 'email1address':
  189                 case 'email2address':
  190                 case 'email3address':
  191                     $regs=array();
  192                     if(isset($message->$msgKey) && preg_match("/.*<(.+)>/", $message->$msgKey, $regs ) ) {
  193                         $message->$msgKey = $regs[1];
  194                     }
  195                 break;
  196             }
  197             if (is_array($grpKey)) {
  198                 if (isset($groupe->{$grpKey[0]})) {
  199                     $tmpData=explode('||',$groupe->{$grpKey[0]});
  200                 } else {
  201                     $tmpData=array();
  202                 }
  203                 if(isset($message->$msgKey)) {
  204                     $tmpData[$grpKey[1]]=$message->$msgKey;
  205                 }
  206                 $groupe->{$grpKey[0]}=implode('||',$tmpData);
  207             } else {
  208                 $groupe->$grpKey=isset($message->$msgKey)?$message->$msgKey:'';
  209             }
  210         }
  211         //debugLog(print_r($groupe,1));
  212         return $groupe;
  213     }
  214 }
  215 class GroupeAppointment {
  216     public $_mapping = array();
  217     public $_deviceProperties;
  218     public $_syncSettings;
  219     public $_timeZone =array();
  220     function __construct() {
  221 
  222     }
  223     function setDeviceProperties($val) {
  224         $this->_deviceProperties=$val;
  225     }
  226     function setSyncSettings($val) {
  227         $this->_syncSettings=$val;
  228     }
  229     function setTimeZone($val) {
  230         $this->_timeZone=$val;
  231     }
  232 
  233     function groupe2message($groupe, $truncsize,$bodypreference=false,$optionbodypreference=false, $mimesupport=0) {
  234         debugLog('groupe2appointment');
  235 
  236         $message=new SyncAppointment();
  237         $message->uid=bin2hex($groupe->UID);
  238         $message->starttime=$groupe->StartDate;
  239         $message->endtime=$groupe->EndDate;
  240         $message->subject=$groupe->Title;
  241 
  242         setMessageBody($message,isset($groupe->Text)?$groupe->Text:'',$bodypreference);
  243         $message->location=$groupe->Place;
  244         $message->categories=$groupe->Categories;
  245         if (isset($groupe->OwnerEmail)) $message->organizeremail=$groupe->OwnerEmail;
  246         if (isset($groupe->OwnerName)) $message->organizername=$groupe->OwnerName;
  247         if (isset($groupe->MyInvitStatus) && $groupe->MyInvitStatus==5) {
  248             $message->busystatus=1;
  249         } else {
  250             $message->busystatus=$groupe->Unsecure?1:2;
  251         }
  252         $message->alldayevent=($groupe->TimeMode==1?1:0);
  253         if ($message->alldayevent && date('His',$message->endtime)=='235959') {
  254             $message->endtime+=1;
  255         }
  256         $message->dtstamp=$groupe->TimeModify;
  257         if ($groupe->AlarmTime) $message->reminder=intval($groupe->AlarmTime/60);
  258         $message->sensitivity=$groupe->EvtPrivat?2:(($groupe->GrantUsers || $groupe->GrantGroups)?0:1);
  259 
  260 
  261         if ($groupe->Unsecure && isset($this->_syncSettings['cal/no_status']) && $this->_syncSettings['cal/no_status']) {
  262             $message->subject='?'.$message->subject;
  263         }
  264         if ($groupe->EvtPrivat && isset($this->_syncSettings['cal/no_privat'])  && $this->_syncSettings['cal/no_privat']) {
  265             $message->subject='#'.$message->subject;
  266         }
  267 
  268 
  269         $tz = $this->_getLocalTZ();
  270         $message->timezone = base64_encode($this->_getSyncBlobFromTZ($tz));
  271 
  272         //debugLog(print_r($groupe->Attendees,1));
  273         if (!empty($groupe->Attendees)) {
  274             foreach ($groupe->Attendees as $val) {
  275                 $attendee=new SyncAttendee();
  276                 $attendee->email=$val['Email'];
  277                 $attendee->name=$val['Name'];
  278                 $attendee->status=$val['Status'];
  279                 switch($val['Type']) {
  280                     case 'u':
  281                         $attendee->type=1;
  282                     break;
  283                     case 'a':
  284                         $attendee->type=1;
  285                     break;
  286                     case 'r':
  287                         $attendee->type=3;
  288                     break;
  289                 }
  290                 $message->attendees[]=$attendee;
  291             }
  292         }
  293         if ($groupe->RecType && $groupe->RecInt) {
  294             $message->recurrence=new SyncRecurrence();
  295             $message->recurrence->interval=$groupe->RecInt;
  296             $message->recurrence->until=($groupe->RecEnd==-1)?0:$groupe->RecEnd;
  297             switch($groupe->RecType) {
  298                 case 1:
  299                     $message->recurrence->type=0;
  300                 break;
  301                 case 2:
  302                     $message->recurrence->type=1;
  303                     $message->recurrence->dayofweek=pow(2,date('w',$groupe->StartDate));
  304                 break;
  305                 case 3:
  306                     $message->recurrence->type=2;
  307                     $message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  308                 break;
  309                 case 5:
  310                     $message->recurrence->type=5;
  311                     $message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  312                     $message->recurrence->monthofyear=date('m',$groupe->StartDate);
  313                 break;
  314             }
  315             if (isset($groupe->Exceptions) && !empty($groupe->Exceptions)) {
  316                 $message->exceptions=array();
  317                 foreach ($groupe->Exceptions as $val) {
  318                     $exception=new SyncAppointment();
  319                     $exception->deleted=1;
  320                     $exception->exceptionstarttime=$val['ExceptionDate'];
  321                     $message->exceptions[]=$exception;
  322                 }
  323             }
  324         }
  325         //debugLog(print_r($message,1));
  326         return $message;
  327     }
  328 
  329 /*
  330     [RecType] => 2
  331     [RecInt] => 1
  332     [RecCfg] =>
  333     [RecEnd] => -1
  334     [Exception] =>
  335 
  336     [NoOwner] => 1
  337 */
  338 
  339     function message2groupe($message,$groupe) {
  340         //global $user;
  341         debugLog('appointment2groupe');
  342         //debugLog(print_r($message,1));
  343         convertMessageBody($message);
  344 
  345         if(isset($message->timezone)) {
  346             $binData=base64_decode($message->timezone);
  347             $tz = $this->_getTZFromSyncBlob($binData);
  348         } else {
  349             $tz = false;
  350         }
  351         if (isset($message->uid) && trim($message->uid)) $groupe->UID=base64_encode(hex2bin(preg_replace('/[^0-9a-f]/i','',$message->uid)));
  352         //debugLog('h2b'.preg_replace('/[^0-9a-f]/i','',$message->uid));
  353 
  354         if (isset($message->alldayevent) && $message->alldayevent) {
  355             if (date('His',$message->endtime)=='000000' && date('d',$message->endtime)!=date('d',$message->starttime)) $message->endtime-=1;
  356         }
  357         $groupe->StartDate=$message->starttime;
  358         $groupe->EndDate=$message->endtime;
  359 
  360 
  361         $groupe->Text=isset($message->body)?$message->body:'';
  362         $groupe->Place=isset($message->location)?$message->location:'';
  363         $groupe->Categories=isset($message->categories)?$message->categories:array();
  364         /*$groupe->OwnerEmail=$message->organizeremail;
  365         $groupe->OwnerName=$message->organizername;*/
  366         $groupe->TimeMode=(isset($message->alldayevent) && $message->alldayevent)?1:0;
  367         $groupe->AlarmTime=isset($message->reminder)?$message->reminder*60:0;
  368 
  369         if (isset($this->_syncSettings['cal/no_status']) && $this->_syncSettings['cal/no_status']) {
  370             $groupe->Unsecure=0;
  371         } else {
  372             $groupe->Unsecure=(isset($message->busystatus) && $message->busystatus==1)?1:0;
  373         }
  374         if (isset($this->_syncSettings['cal/no_privat']) && $this->_syncSettings['cal/no_privat']) {
  375             debugLog('NoPrivateSupport');
  376             $groupe->EvtPrivat=0;
  377             $groupe->_setDefaultGrant=1;
  378         } else {
  379             if (!isset($message->sensitivity)) $message->sensitivity=0;
  380             debugLog('Sensitivity:'.$message->sensitivity);
  381             if (isset($message->sensitivity) && in_array($message->sensitivity,array(2,3))) {
  382                 $groupe->EvtPrivat=1;
  383                 debugLog('SetPrivate:'.$message->sensitivity);
  384             } else {
  385                 $groupe->EvtPrivat=0;
  386             }
  387             if (in_array($message->sensitivity,array(0,1,2))) {
  388                 $groupe->_setDefaultGrant=1;
  389                 debugLog('SetDefaultGrant:'.$message->sensitivity);
  390             } else {
  391                 $groupe->_setDefaultGrant=0;
  392             }
  393         }
  394 
  395         $testTitle=trim($message->subject);
  396         do {
  397             $check=false;
  398             if (substr($testTitle,0,1)=='#') {
  399                 $testTitle=substr($testTitle,1);
  400                 $groupe->EvtPrivat=1;
  401                 debugLog('SetPrivate:FromTitle');
  402                 $check=true;
  403             }
  404             if (substr($testTitle,0,1)=='?') {
  405                 $testTitle=substr($testTitle,1);
  406                 $groupe->Unsecure=1;
  407                 debugLog('SetUnsure:FromTitle');
  408                 $check=true;
  409             }
  410         } while ($check);
  411         $groupe->Title=trim($testTitle);
  412 
  413         $groupe->Attendees=array();
  414         if (!empty($message->attendees)) {
  415             foreach ($message->attendees as $val) {
  416                 if (!trim($val->email)) continue;
  417                 $groupe->Attendees[]=array(
  418                     'Email'=>$val->email,
  419                     'Name'=>trim($val->name),
  420                     'Status'=>isset($val->status)?$val->status:0,
  421                     'Type'=>(isset($val->type) && $val->type==3)?'r':'',
  422                 );
  423             }
  424         }
  425         $groupe->Exceptions=array();
  426         $groupe->RecType=0;
  427         $groupe->RecInt=0;
  428         if (isset($message->recurrence)) {
  429             $badRecur=false;
  430             switch($message->recurrence->type) {
  431                 case 0:
  432                     $groupe->RecType=1;
  433                 break;
  434                 case 1:
  435                     $groupe->RecType=2;
  436                     //$message->recurrence->dayofweek=pow(2,date('w',$groupe->StartDate));
  437                 break;
  438                 case 2:
  439                     $groupe->RecType=3;
  440                     //$message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  441                 break;
  442                 case 5:
  443                     $groupe->RecType=5;
  444                     //$message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  445                     //$message->recurrence->monthofyear=date('m',$groupe->StartDate);
  446                 break;
  447                 default:
  448                     $badRecur=true;
  449                 break;
  450             }
  451             if (!$badRecur) {
  452                 if (isset($message->recurrence->interval) && $message->recurrence->interval) {
  453                     $groupe->RecInt=$message->recurrence->interval;
  454                 } else {
  455                     $groupe->RecInt=1;
  456                 }
  457                 if (isset($message->recurrence->until) && $message->recurrence->until) {
  458                     $groupe->RecEnd=($message->recurrence->until>=2147385000)?-1:$message->recurrence->until;
  459                 } else {
  460                     $groupe->RecEnd=-1;
  461                     if (isset($message->recurrence->occurrences) && $message->recurrence->occurrences)  {
  462                         $recCount=$message->recurrence->occurrences-1;
  463                         $year=date('Y',$groupe->StartDate);
  464                         $month=date('m',$groupe->StartDate);
  465                         $day=date('d',$groupe->StartDate);
  466                         switch ($groupe->RecType) {
  467                             case 1:
  468                                 $groupe->RecEnd=mktime(23,59,59,$month,$day+$groupe->RecInt*$recCount,$year);
  469                             break;
  470                             case 2:
  471                                 $groupe->RecEnd=mktime(23,59,59,$month,$day+$groupe->RecInt*7*$recCount,$year);
  472                             break;
  473                             case 3:
  474                                 $groupe->RecEnd=mktime(23,59,59,$month+$groupe->RecInt*$recCount,$day,$year);
  475                             break;
  476                             case 5:
  477                                 $groupe->RecEnd=mktime(23,59,59,$month,$day,$year+$groupe->RecInt*$recCount);
  478                             break;
  479                         }
  480                     }
  481                 }
  482 
  483                 if (isset($message->exceptions) && !empty($message->exceptions)) {
  484                     foreach ($message->exceptions as $val) {
  485                         $exception=array(
  486                             'Deleted'=>$val->deleted,
  487                             'ExceptionDate'=>$val->exceptionstarttime,
  488                         );
  489                         if (!$val->deleted) {
  490                             if (isset($val->subject)) $exception['Title']=$val->subject;
  491                             if (isset($val->body)) $exception['Text']=$val->body;
  492                             if (isset($val->location)) $exception['Place']=$val->location;
  493                             if (isset($val->starttime)) $exception['StartDate']=$val->starttime;
  494                             if (isset($val->endtime)) $exception['EndDate']=$val->endtime;
  495                             if (isset($val->reminder)) $exception['AlarmTime']=$val->reminder*60;
  496                             if (isset($val->alldayevent)) $exception['TimeMode']=$val->alldayevent?1:0;
  497                             if (isset($val->busystatus)) $exception['Unsecure']=$val->busystatus==1?1:0;
  498                         }
  499                         $groupe->Exceptions[]=$exception;
  500                     }
  501                 }
  502             } else {
  503                 $groupe->RecType=0;
  504             }
  505         }
  506 
  507         //debugLog(print_r($groupe,1));
  508         return $groupe;
  509 
  510         //nokia sends an yearly event with 0 mins duration but as all day event,
  511         //so make it end next day
  512         /*if ($message->starttime == $message->endtime && isset($message->alldayevent) && $message->alldayevent) {
  513             $message->endtime = $message->starttime + 24 * 60 * 60;
  514         }*/
  515 
  516         //debugLog(print_r($message,1));
  517 
  518         //return $groupe;
  519     }
  520 
  521    // Unpack timezone info from Sync
  522     function _getTZFromSyncBlob($data) {
  523         $tz = unpack("lbias/a64name/vdstendyear/vdstendmonth/vdstendday/vdstendweek/vdstendhour/vdstendminute/vdstendsecond/vdstendmillis/" .
  524             "lstdbias/a64name/vdststartyear/vdststartmonth/vdststartday/vdststartweek/vdststarthour/vdststartminute/vdststartsecond/vdststartmillis/" .
  525             "ldstbias", $data);
  526         // Make the structure compatible with class.recurrence.php
  527         $tz["timezone"] = $tz["bias"];
  528         $tz["timezonedst"] = $tz["dstbias"];
  529         return $tz;
  530     }
  531 
  532     // Pack timezone info for Sync
  533     function _getSyncBlobFromTZ($tz) {
  534         $packed = pack("la64vvvvvvvv" . "la64vvvvvvvv" . "l",
  535                 $tz["bias"], "", 0, $tz["dstendmonth"], $tz["dstendday"], $tz["dstendweek"], $tz["dstendhour"], $tz["dstendminute"], $tz["dstendsecond"], $tz["dstendmillis"],
  536                 $tz["stdbias"], "", 0, $tz["dststartmonth"], $tz["dststartday"], $tz["dststartweek"], $tz["dststarthour"], $tz["dststartminute"], $tz["dststartsecond"], $tz["dststartmillis"],
  537                 $tz["dstbias"]);
  538 
  539         return $packed;
  540     }
  541 
  542     // Checks the date to see if it is in DST, and returns correct GMT date accordingly
  543     function _getGMTTimeByTZ($localtime, $tz) {
  544         if(!isset($tz) || !is_array($tz))
  545             return $localtime;
  546 
  547         if($this->_isDST($localtime, $tz))
  548             return $localtime + $tz["bias"]*60 + $tz["dstbias"]*60;
  549         else
  550             return $localtime + $tz["bias"]*60;
  551     }
  552 
  553     // Returns the local time for the given GMT time, taking account of the given timezone
  554     function _getLocaltimeByTZ($gmttime, $tz) {
  555         if(!isset($tz) || !is_array($tz))
  556             return $gmttime;
  557 
  558         if($this->_isDST($gmttime - $tz["bias"]*60, $tz)) // may bug around the switch time because it may have to be 'gmttime - bias - dstbias'
  559             return $gmttime - $tz["bias"]*60 - $tz["dstbias"]*60;
  560         else
  561             return $gmttime - $tz["bias"]*60;
  562     }
  563 
  564     // Returns TRUE if it is the summer and therefore DST is in effect
  565     function _isDST($localtime, $tz) {
  566         if(!isset($tz) || !is_array($tz))
  567             return false;
  568 
  569         $year = gmdate("Y", $localtime);
  570         $start = $this->_getTimestampOfWeek($year, $tz["dststartmonth"], $tz["dststartweek"], $tz["dststartday"], $tz["dststarthour"], $tz["dststartminute"], $tz["dststartsecond"]);
  571         $end = $this->_getTimestampOfWeek($year, $tz["dstendmonth"], $tz["dstendweek"], $tz["dstendday"], $tz["dstendhour"], $tz["dstendminute"], $tz["dstendsecond"]);
  572 
  573         if($start < $end) {
  574             // northern hemisphere (july = dst)
  575           if($localtime >= $start && $localtime < $end)
  576               $dst = true;
  577           else
  578               $dst = false;
  579         } else {
  580             // southern hemisphere (january = dst)
  581           if($localtime >= $end && $localtime < $start)
  582               $dst = false;
  583           else
  584               $dst = true;
  585         }
  586 
  587         return $dst;
  588     }
  589     function _getGMTTZ() {
  590         $tz = array(
  591             "bias" => 0,
  592             "stdbias" => 0,
  593             "dstbias" => 0,
  594             "dstendyear" => 0,
  595             "dstendmonth" =>0,
  596             "dstendday" =>0,
  597             "dstendweek" => 0,
  598             "dstendhour" => 0,
  599             "dstendminute" => 0,
  600             "dstendsecond" => 0,
  601             "dstendmillis" => 0,
  602             "dststartyear" => 0,
  603             "dststartmonth" =>0,
  604             "dststartday" =>0,
  605             "dststartweek" => 0,
  606             "dststarthour" => 0,
  607             "dststartminute" => 0,
  608             "dststartsecond" => 0,
  609             "dststartmillis" => 0
  610         );
  611         return $tz;
  612     }
  613     function _getLocalTZ() {
  614         if (is_array($this->_timeZone) && !empty($this->_timeZone)) {
  615             return $this->_timeZone;
  616         } else {
  617             return $this->_getGMTTZ();
  618         }
  619     }
  620     // Returns the local timestamp for the $week'th $wday of $month in $year at $hour:$minute:$second
  621     function _getTimestampOfWeek($year, $month, $week, $wday, $hour, $minute, $second)
  622     {
  623         $date = gmmktime($hour, $minute, $second, $month, 1, $year);
  624 
  625         // Find first day in month which matches day of the week
  626         while(1) {
  627             $wdaynow = gmdate("w", $date);
  628             if($wdaynow == $wday)
  629                 break;
  630             $date += 24 * 60 * 60;
  631         }
  632 
  633         // Forward $week weeks (may 'overflow' into the next month)
  634         $date = $date + $week * (24 * 60 * 60 * 7);
  635 
  636         // Reverse 'overflow'. Eg week '10' will always be the last week of the month in which the
  637         // specified weekday exists
  638         while(1) {
  639             $monthnow = gmdate("n", $date) - 1; // gmdate returns 1-12
  640             if($monthnow > $month)
  641                 $date = $date - (24 * 7 * 60 * 60);
  642             else
  643                 break;
  644         }
  645 
  646         return $date;
  647     }
  648 
  649     // Normalize the given timestamp to the start of the day
  650     function _getDayStartOfTimestamp($timestamp) {
  651         return $timestamp - ($timestamp % (60 * 60 * 24));
  652     }
  653 
  654 
  655 
  656 }
  657 class GroupeTask {
  658     public $_mapping = array();
  659     public $_deviceProperties;
  660     public $_syncSettings;
  661     function __construct() {
  662 
  663     }
  664     function setDeviceProperties($val) {
  665         $this->_deviceProperties=$val;
  666     }
  667     function setSyncSettings($val) {
  668         $this->_syncSettings=$val;
  669     }
  670     function groupe2message($groupe, $truncsize,$bodypreference=false,$optionbodypreference=false, $mimesupport=0) {
  671 
  672         debugLog('groupe2task');
  673         //"meetingstatus"
  674 
  675 
  676     /*
  677     var $utcduedate;
  678     var $utcstartdate;
  679 
  680     var $recurrence;
  681     var $regenerate;
  682     var $deadoccur;*/
  683 
  684 
  685         $message=new SyncTask();
  686         setMessageBody($message,isset($groupe->Text)?$groupe->Text:'',$bodypreference);
  687         $message->subject=$groupe->Title;
  688         $message->categories=$groupe->Categories;
  689 
  690 
  691         $message->utcstartdate=$groupe->StartDate;
  692         $message->utcduedate=$groupe->EndDate;
  693         $message->startdate=$groupe->StartDate+date('Z');
  694         $message->duedate=$groupe->EndDate+date('Z');
  695         //debugLog('StartDate:'.date('d.m.Y H:i',$message->startdate));
  696 
  697         switch($groupe->Priority) {
  698             case 0:
  699                 $message->importance=2;
  700             break;
  701             case 1:
  702                 $message->importance=1;
  703             break;
  704             case 2:
  705                 $message->importance=0;
  706             break;
  707         }
  708         if ($groupe->UserDone==4 || $groupe->Status==4) {
  709             $message->complete=1;
  710             $message->datecompleted=$groupe->StatusDate;
  711         } else {
  712             $message->complete=0;
  713         }
  714         if ($groupe->Alarm) {
  715             $message->reminderset=0;
  716             $message->remindertime=$groupe->EndDate-$groupe->Alarm*3600*38;
  717         }
  718         switch($groupe->UserTaskType) {
  719             case 't':
  720                 $message->sensitivity=0;
  721             break;
  722             case 'd':
  723                 $message->sensitivity=0;
  724             break;
  725             case 'p':
  726                 $message->sensitivity=2;
  727             break;
  728             case 'o':
  729                 $message->sensitivity=2;
  730             break;
  731         }
  732 
  733 
  734         if ($groupe->RecType && $groupe->RecInt) {
  735             $message->recurrence=new SyncTaskRecurrence();
  736             $message->recurrence->start=$message->startdate;
  737             $message->recurrence->interval=$groupe->RecInt;
  738             //$message->recurrence->regenerate=1;
  739             if ($groupe->RecDate!=-1) $message->recurrence->until=$groupe->RecDate;
  740             switch($groupe->RecType) {
  741                 case 1:
  742                     $message->recurrence->type=0;
  743                 break;
  744                 case 2:
  745                     $message->recurrence->type=1;
  746                     $message->recurrence->dayofweek=pow(2,date('w',$groupe->StartDate));
  747                 break;
  748                 case 3:
  749                     $message->recurrence->type=2;
  750                     $message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  751                 break;
  752                 case 5:
  753                     $message->recurrence->type=5;
  754                     $message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  755                     $message->recurrence->monthofyear=date('m',$groupe->StartDate);
  756                 break;
  757             }
  758         }
  759         //debugLog(print_r($message,1));
  760         return $message;
  761     }
  762     function message2groupe($message,$groupe) {
  763         //global $user;
  764         debugLog('task2groupe');
  765 
  766         convertMessageBody($message);
  767 
  768         //debugLog(print_r($message,1));
  769 
  770         if (!isset($message->utcstartdate) || !$message->utcstartdate) {
  771             $groupe->StartDate=mktime(0,0,0);
  772         } else {
  773             $groupe->StartDate=$message->utcstartdate;
  774         }
  775         if (!isset($message->utcduedate) || !$message->utcduedate) {
  776             $groupe->EndDate=$groupe->StartDate;
  777         } else {
  778             $groupe->EndDate=$message->utcduedate;
  779         }
  780         $groupe->Title=$message->subject;
  781         $groupe->Text=isset($message->body)?$message->body:'';
  782         $groupe->Categories=isset($message->categories)?$message->categories:array();
  783 
  784         switch($message->importance) {
  785             case 0:
  786                 $groupe->Priority=2;
  787             break;
  788             case 1:
  789                 $groupe->Priority=1;
  790             break;
  791             case 2:
  792                 $groupe->Priority=0;
  793             break;
  794         }
  795         if ($message->complete) {
  796             $groupe->UserDone=4;
  797             //$groupe->UserDone=4;
  798         } else {
  799             $groupe->UserDone=1;
  800         }
  801         if (isset($message->remindertime) && $message->remindertime) {
  802             $groupe->Alarm=floor(($message->duedate-$message->remindertime)/3600/24);
  803         } else {
  804             $groupe->Alarm=0;
  805         }
  806 
  807         $groupe->RecType=0;
  808         $groupe->RecInt=0;
  809         if (isset($message->recurrence)) {
  810             $badRecur=false;
  811             switch($message->recurrence->type) {
  812                 case 0:
  813                     $groupe->RecType=1;
  814                 break;
  815                 case 1:
  816                     $groupe->RecType=2;
  817                     //$message->recurrence->dayofweek=pow(2,date('w',$groupe->StartDate));
  818                 break;
  819                 case 2:
  820                     $groupe->RecType=3;
  821                     //$message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  822                 break;
  823                 case 5:
  824                     $groupe->RecType=5;
  825                     //$message->recurrence->dayofmonth=date('d',$groupe->StartDate);
  826                     //$message->recurrence->monthofyear=date('m',$groupe->StartDate);
  827                 break;
  828                 default:
  829                     $badRecur=true;
  830                 break;
  831             }
  832             if (!$badRecur) {
  833                 if (isset($message->recurrence->interval) && $message->recurrence->interval) {
  834                     $groupe->RecInt=$message->recurrence->interval;
  835                 } else {
  836                     $groupe->RecInt=0;
  837                 }
  838                 if (isset($message->recurrence->until) && $message->recurrence->until) {
  839                     $groupe->RecDate=$message->recurrence->until;
  840                 } else {
  841                     $groupe->RecDate=-1;
  842                     if (isset($message->recurrence->occurrences) && $message->recurrence->occurrences)  {
  843                         $recCount=$message->recurrence->occurrences-1;
  844                         $year=date('Y',$groupe->StartDate);
  845                         $month=date('m',$groupe->StartDate);
  846                         $day=date('d',$groupe->StartDate);
  847                         switch ($groupe->RecType) {
  848                             case 1:
  849                                 $groupe->RecDate=mktime(23,59,59,$month,$day+$groupe->RecInt*$recCount,$year);
  850                             break;
  851                             case 2:
  852                                 $groupe->RecDate=mktime(23,59,59,$month,$day+$groupe->RecInt*7*$recCount,$year);
  853                             break;
  854                             case 3:
  855                                 $groupe->RecDate=mktime(23,59,59,$month+$groupe->RecInt*$recCount,$day,$year);
  856                             break;
  857                             case 5:
  858                                 $groupe->RecDate=mktime(23,59,59,$month,$day,$year+$groupe->RecInt*$recCount);
  859                             break;
  860                         }
  861                     }
  862                 }
  863             } else {
  864                 $groupe->RecType=0;
  865             }
  866         }
  867         //debugLog(print_r($groupe,1));
  868         return $groupe;
  869     }
  870 
  871 }
  872 class GroupeMail {
  873     public $_mapping = array();
  874     public $_deviceProperties;
  875     public $_syncSettings;
  876     function __construct() {
  877 
  878     }
  879     function setDeviceProperties($val) {
  880         $this->_deviceProperties=$val;
  881     }
  882     function setSyncSettings($val) {
  883         $this->_syncSettings=$val;
  884     }
  885     function getBodyPreferenceBestMatch($bodypreference) {
  886         // The best choice is RTF, then HTML and then MIME in order to save bandwidth
  887         // because MIME is a complete message including the headers and attachments
  888         //if (isset($bodypreference[3]))  return 'RTF';
  889         if (isset($bodypreference[2]))  return 'HTML';
  890         if (isset($bodypreference[4]))  return 'MIME';
  891         return 'PLAIN';
  892     }
  893     function groupe2message($groupe, $truncsize,$bodypreference=false,$optionbodypreference=false, $mimesupport=0) {
  894         debugLog('groupe2mail: truncsize:'.$truncsize.' bodypreference:'.print_r($bodypreference,1).' optionbodypreference:'.print_r($optionbodypreference,1).' mimesupport:'.$mimesupport);
  895         //debugLog(print_r($this->_syncSettings,1));
  896     
  897         $mail=array(
  898             base64_decode($groupe->MimeHeader),
  899             base64_decode($groupe->MimeBody),
  900         );
  901         $mobj = new Mail_mimeDecode($mail);
  902         debugLog("RAW Message ".substr($mail[0],0,200));
  903         $message = $mobj->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'crlf' => "\n", 'charset' => BACKEND_CHARSET));
  904         //debugLog("RAW Message ".print_r($message,true));
  905         $output = new SyncMail();
  906         
  907         // start AS12 Stuff (bodypreference === false) case = old behaviour
  908         if ($bodypreference===false) {
  909             $body = BackendGroupe::getBody($message);
  910             $body = str_replace("\n","\r\n", str_replace("\r","",$body));
  911             $output->bodysize = strlen($body);
  912             if (!$truncsize) $truncsize=MAX_EMBEDDED_SIZE;
  913             if(strlen($body) > $truncsize) {
  914                 $body = utf8_truncate($body, $truncsize);
  915                 $output->bodytruncated = 1;
  916             } else {
  917                 $body = $body;
  918                 $output->bodytruncated = 0;
  919             }
  920             $output->body = $body;
  921         } else {
  922             if ($mimesupport==0 && isset($bodypreference[4])) {
  923                 unset($bodypreference[4]);
  924                 debugLog('Remove mime body preference type because the device required no mime support');
  925             }
  926             $mailType = $this->getBodyPreferenceBestMatch($bodypreference);
  927             
  928             if (isset($bodypreference[1]) && !isset($bodypreference[1]["TruncationSize"]))
  929                 $bodypreference[1]["TruncationSize"] = MAX_EMBEDDED_SIZE;
  930             if (isset($bodypreference[2]) && !isset($bodypreference[2]["TruncationSize"]))
  931                 $bodypreference[2]["TruncationSize"] = MAX_EMBEDDED_SIZE;
  932             if (isset($bodypreference[3]) && !isset($bodypreference[3]["TruncationSize"]))
  933                 $bodypreference[3]["TruncationSize"] = MAX_EMBEDDED_SIZE;
  934             if (isset($bodypreference[4]) && !isset($bodypreference[4]["TruncationSize"]))
  935                 $bodypreference[4]["TruncationSize"] = MAX_EMBEDDED_SIZE;
  936             $output->airsyncbasebody = new SyncAirSyncBaseBody();
  937             debugLog("airsyncbasebody!");
  938             $body="";
  939             BackendGroupe::getBodyRecursive($message, "html", $body);
  940             if ($body != "") {
  941                 $output->airsyncbasenativebodytype=2;
  942             } else {
  943                 $output->airsyncbasenativebodytype=1;
  944                 BackendGroupe::getBodyRecursive($message, "plain", $body);
  945             }
  946             $body = str_replace("\n","\r\n", str_replace("\r","",$body));
  947             if ($mailType=='MIME') {
  948                 debugLog("MIME Body");
  949                 $output->airsyncbasebody->type = 4;
  950                 $rawmessage = $mobj->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'crlf' => "\n", 'charset' => BACKEND_CHARSET));
  951                 $body = "";
  952                 foreach($rawmessage->headers as $key=>$value) {
  953                     if ($key != "content-type" && $key != "mime-version" && $key != "content-transfer-encoding" &&
  954                         !is_array($value)) {
  955                         $body .= $key.":";
  956                         $tokens = explode(" ",trim($value));
  957                         $line = "";
  958                         foreach($tokens as $valu) {
  959                             if ((strlen($line)+strlen($valu)+2) > 60) {
  960                                 $line .= "\n";
  961                                 $body .= $line;
  962                                 $line = " ".$valu;
  963                             } else {
  964                                 $line .= " ".$valu;
  965                             }
  966                         }
  967                         $body .= $line."\n";
  968                     }
  969                 }
  970                 unset($rawmessage);
  971                 $mimemsg = new Mail_mime(array( 'head_encoding' => 'quoted-printable',
  972                                                 'text_encoding' => 'quoted-printable',
  973                                                 'html_encoding' => 'base64',
  974                                                 'head_charset'  => 'utf-8',
  975                                                 'text_charset'  => 'utf-8',
  976                                                 'html_charset'  => 'utf-8',
  977                                                 'eol'       => "\n",
  978                                                 'delay_file_io' => false,
  979                                             )
  980                                         );
  981                 BackendGroupe::GetAttachmentsRecursive($message,$mimemsg);
  982                 if ($output->airsyncbasenativebodytype==1) {
  983                     BackendGroupe::getBodyRecursive($message, "plain", $plain);
  984                     BackendGroupe::getBodyRecursive($message, "html", $html);
  985                     if ($html == "") {
  986                         BackendGroupe::getBodyRecursive($message, "plain", $html);
  987                     }
  988                     if ($html == "" && $plain == "" && strlen($mobj->_body) != "") {
  989 //                          debugLog("mobj->_body = ".$mobj->_body);
  990 //                          $plain = $html = $mobj->_quotedPrintableDecode($mobj->_body);
  991                         $body .= "Content-Type:".$message->headers['content-type']."\r\n";
  992                         $body .= "Content-Transfer-Encoding:".$message->headers['content-transfer-encoding']."\r\n";
  993                         $body .= "\n\n".$mobj->_body;
  994                         $output->airsyncbasebody->data = $body;
  995                     }
  996                     $mimemsg->setTXTBody(str_replace("\n","\r\n", str_replace("\r","",w2u($plain))));
  997                     $html = '<html>'.
  998                             '<head>'.
  999                             '<meta name="Generator" content="Z-Push">'.
 1000                             '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'.
 1001                             '</head>'.
 1002                             '<body>'.
 1003                             str_replace("\n","<BR>",str_replace("\r","", str_replace("\r\n","<BR>",w2u($html)))).
 1004                             '</body>'.
 1005                             '</html>';
 1006                     $mimemsg->setHTMLBody(str_replace("\n","\r\n", str_replace("\r","",$html)));
 1007                 }
 1008                 if ($output->airsyncbasenativebodytype==2) {
 1009                     BackendGroupe::getBodyRecursive($message, "plain", $plain);
 1010                     if ($plain == "") {
 1011                         BackendGroupe::getBodyRecursive($message, "html", $plain);
 1012                         // remove css-style tags
 1013                         $plain = preg_replace("/<style.*?<\/style>/is", "", $plain);
 1014                         // remove all other html
 1015                         $plain = preg_replace("/<br.*>/is","<br>",$plain);
 1016                         $plain = preg_replace("/<br >/is","<br>",$plain);
 1017                         $plain = preg_replace("/<br\/>/is","<br>",$plain);
 1018                         $plain = str_replace("<br>","\r\n",$plain);
 1019                         $plain = strip_tags($plain);
 1020                     }
 1021                     $mimemsg->setTXTBody(str_replace("\n","\r\n", str_replace("\r","",w2u($plain))));
 1022                     BackendGroupe::getBodyRecursive($message, "html", $html);
 1023                     $mimemsg->setHTMLBody(str_replace("\n","\r\n", str_replace("\r","",w2u($html))));
 1024                 }
 1025                 if (!isset($output->airsyncbasebody->data))
 1026                     $output->airsyncbasebody->data = $body.$mimemsg->txtheaders()."\n\n".$mimemsg->get();
 1027                 $output->airsyncbasebody->estimateddatasize = strlen($output->airsyncbasebody->data);
 1028             } elseif ($mailType=='HTML') {
 1029                 debugLog("HTML Body");
 1030                 // Send HTML if requested and native type was html
 1031                 $output->airsyncbasebody->type = 2;
 1032                 BackendGroupe::getBodyRecursive($message, "plain", $plain);
 1033                 BackendGroupe::getBodyRecursive($message, "html", $html);
 1034                 if ($html == "") {
 1035                     BackendGroupe::getBodyRecursive($message, "plain", $html);
 1036                 }
 1037                 if ($html == "" && $plain == "" && strlen($mobj->_body) > 0) {
 1038                     $plain = $html = $mobj->_quotedPrintableDecode($mobj->_body);
 1039                 }
 1040                 //debugLog(print_r($html,1));
 1041                 if ($output->airsyncbasenativebodytype==2) {
 1042                     $html = w2u($html);
 1043                 } else {
 1044                     $html = '<html>'.
 1045                             '<head>'.
 1046                             '<meta name="Generator" content="Z-Push">'.
 1047                             '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'.
 1048                             '</head>'.
 1049                             '<body>'.
 1050                             str_replace("\n","<BR>",str_replace("\r","<BR>", str_replace("\r\n","<BR>",w2u($plain)))).
 1051                             '</body>'.
 1052                             '</html>';
 1053                 }
 1054                 if(isset($bodypreference[2]["TruncationSize"]) &&
 1055                     strlen($html) > $bodypreference[2]["TruncationSize"]) {
 1056                     $html = utf8_truncate($html,$bodypreference[2]["TruncationSize"]);
 1057                     $output->airsyncbasebody->truncated = 1;
 1058                 }
 1059                 $output->airsyncbasebody->data = $html;
 1060                 $output->airsyncbasebody->estimateddatasize = strlen($html);
 1061             } else {
 1062                     // Send Plaintext as Fallback or if original body is plaintext
 1063                 debugLog("Plaintext Body");
 1064                 BackendGroupe::getBodyRecursive($message, "plain", $plain);
 1065                 if ($plain == "" && strlen($mobj->_body) > 0) {
 1066 //                      $plain = $mobj->_quotedPrintableDecode($mobj->_body);
 1067                     $plain="";
 1068                 }
 1069                 $plain = w2u(str_replace("\n","\r\n",str_replace("\r","",$plain)));
 1070                 $output->airsyncbasebody->type = 1;
 1071                 if(isset($bodypreference[1]["TruncationSize"]) &&
 1072                     strlen($plain) > $bodypreference[1]["TruncationSize"]) {
 1073                     $plain = utf8_truncate($plain, $bodypreference[1]["TruncationSize"]);
 1074                     $output->airsyncbasebody->truncated = 1;
 1075                 }
 1076                 $output->airsyncbasebody->estimateddatasize = strlen($plain);
 1077                 $output->airsyncbasebody->data = $plain;
 1078             }
 1079             // In case we have nothing for the body, send at least a blank...
 1080             // dw2412 but only in case the body is not rtf!
 1081             if ($output->airsyncbasebody->type != 3 && (!isset($output->airsyncbasebody->data) || strlen($output->airsyncbasebody->data) == 0))
 1082                 $output->airsyncbasebody->data = " ";
 1083         }
 1084         // end AS12 Stuff
 1085         // small dirty correction for (i.e. Tobit David) since it has the opinion the UTC Timezone abbreviation is UT :-(
 1086         $output->datereceived = isset($message->headers["date"]) ? strtotime($message->headers["date"].(substr($message->headers["date"],-3)==" UT" ? "C" : "")) : null;
 1087         $output->displayto = isset($message->headers["to"]) ? trim(w2u($message->headers["to"])) : null;
 1088         $output->importance = isset($message->headers["x-priority"]) ? preg_replace("/\D+/", "", $message->headers["x-priority"]) : null;
 1089         $output->messageclass = "IPM.Note";
 1090         if (strtolower($message->ctype_primary) == "multipart") {
 1091             switch(strtolower($message->ctype_secondary)) {
 1092                 case 'signed'   :
 1093                     $output->messageclass = "IPM.Note.SMIME.MultipartSigned"; break;
 1094                 default     :
 1095                     $output->messageclass = "IPM.Note";
 1096             }
 1097         }
 1098         if (isset($message->headers["subject"])) {
 1099             if (is_array($message->headers["subject"])) $message->headers["subject"]=$message->headers["subject"][0];
 1100             $output->subject = trim(w2u($message->headers["subject"]));
 1101         } else {
 1102             $output->subject = "";
 1103         }
 1104         $output->read =$groupe->New?0:1;
 1105         $output->to = isset($message->headers["to"]) ? trim(w2u($message->headers["to"])) : null;
 1106         $output->cc = isset($message->headers["cc"]) ? trim(w2u($message->headers["cc"])) : null;
 1107         $output->from = isset($message->headers["from"]) ? trim(w2u($message->headers["from"])) : null;
 1108         $output->reply_to = isset($message->headers["reply-to"]) ? trim(w2u($message->headers["reply-to"])) : null;
 1109         // start AS12 Stuff
 1110         $output->poommailflag = new SyncPoommailFlag();
 1111         $output->poommailflag->flagstatus = 0;
 1112         $output->internetcpid = 65001;
 1113         $output->contentclass="urn:content-classes:message";
 1114         // end AS12 Stuff
 1115         if(strcasecmp($message->ctype_primary,"multipart")==0 && isset($message->parts) && is_array($message->parts)) {
 1116             BackendGroupe::setAttachmentsRecursive($groupe->box . ":" . $groupe->id,$message,$output);
 1117         }
 1118         // unset mimedecoder & mail
 1119         unset($mobj);
 1120         unset($mail);
 1121         unset($message);
 1122         //debugLog('groupe2mail:'.print_r($output,1));
 1123         return $output;
 1124     }
 1125     function message2groupe($message,$groupe) {
 1126         //debugLog(print_r($groupe,1));
 1127         return $groupe;
 1128     }
 1129 
 1130 } 
 1131 
 1132 class BackendGroupe extends BackendDiff {
 1133     public $_user;
 1134     public $_devid;
 1135     public $_protocolversion;
 1136     public $_GroupeFolders=array("VIRTUAL/calendar","VIRTUAL/contacts","VIRTUAL/tasks");
 1137     public $_deviceProperties=array();
 1138     public $_syncSettings=array();
 1139     public $_statMessages=array();
 1140     public $_soap;
 1141     public $_messages;
 1142     public $_mailLimit=100;
 1143 
 1144     public function __construct() {
 1145         $this->_soap=new GroupeSoapClient();
 1146         $this->_map['contact']=new GroupeContact();
 1147         $this->_map['appointment']=new GroupeAppointment();
 1148         $this->_map['task']=new GroupeTask();
 1149         $this->_map['mail']=new GroupeMail();
 1150         if (defined('GROUP_MAIL_LIMIT')) {
 1151             $this->_mailLimit=GROUP_MAIL_LIMIT;
 1152         }
 1153     }
 1154 
 1155     function Logon($username, $domain, $password) {
 1156         $this->_wasteID = false;
 1157         $this->_soap->initUser($username,$password);
 1158         if ($this->_soap->call('logon')) {
 1159             debugLog('Groupe::'.$username.' logged in');
 1160             $this->_importedFolders = array();
 1161             $this->_loggedin = TRUE;
 1162             return true;
 1163         } else {
 1164             debugLog('Groupe::Logon('.$username.','.$domain.',****) failed!!');
 1165             return false;
 1166         }
 1167     }
 1168     // completing protocol
 1169     function Logoff() {
 1170         global $cmd;
 1171         debugLog('Groupe::Logoff / cmd:'.$cmd);
 1172         //do not update last sync time on ping and provision
 1173         if (isset($cmd) && $cmd != '' && $cmd != 'Ping' && $cmd != 'Provision' ) {
 1174             $this->setLastSyncTime();
 1175             debugLog('Groupe::FolderChanges:'.print_r($this->_importedFolders,1));
 1176             foreach($this->_importedFolders as $folderid=>$changes) {
 1177                 //debugLog('Groupe::FolderStatus:'.$folderid);
 1178             }
 1179             $this->_loggedin = FALSE;
 1180 
 1181         }
 1182         return true;
 1183     }
 1184     function Setup($user, $devid, $protocolversion) {
 1185         debugLog('Groupe::Setup('.$user.','.$devid.','.$protocolversion.')');
 1186         $this->_user = $user;
 1187         $this->_devid = $devid;
 1188         $this->_protocolversion = $protocolversion;
 1189         if ($this->_devid) {
 1190             $this->_deviceProperties=$this->getDeviceProperties($this->_devid);
 1191             $this->_syncSettings=$this->getSyncSettings($this->_devid);
 1192 
 1193             //$this->_mailProperties=$this->_soap->call('getActiveSyncMailPoperties',array());
 1194             //debugLog(print_r($this->_mailProperties,true));
 1195 
 1196             $this->_map['contact']->setDeviceProperties($this->_deviceProperties);
 1197             $this->_map['contact']->setSyncSettings($this->_syncSettings);
 1198 
 1199             $this->_map['appointment']->setDeviceProperties($this->_deviceProperties);
 1200             $this->_map['appointment']->setSyncSettings($this->_syncSettings);
 1201             $this->_map['appointment']->setTimeZone($this->_soap->call('getActiveSyncTimeZone',array()));
 1202 
 1203             $this->_map['task']->setDeviceProperties($this->_deviceProperties);
 1204             $this->_map['task']->setSyncSettings($this->_syncSettings);
 1205 
 1206             $this->_map['mail']->setDeviceProperties($this->_deviceProperties);
 1207             $this->_map['mail']->setSyncSettings($this->_syncSettings);
 1208         }
 1209         return true;
 1210     }
 1211     function getDeviceProperties($devid) {
 1212         $soapResult=$this->_soap->call('getActiveSyncDevicePoperties',array($devid));
 1213         if (!$soapResult) {
 1214             $deviceProperties=array(
 1215                 'Type'=>$_REQUEST["DeviceType"],
 1216                 'Agent'=>$_SERVER["HTTP_USER_AGENT"],
 1217                 'LastSync'=>0,
 1218             );
 1219             $this->_soap->call('setActiveSyncDevicePoperties',array($devid,(object)$this->_deviceProperties));
 1220         } else {
 1221             $deviceProperties=(array)$soapResult;
 1222         }
 1223         return  $deviceProperties;
 1224     }
 1225     function getSyncSettings($devid) {
 1226         $soapResult=$this->_soap->call('getActiveSyncSyncSettings',array($devid));
 1227         if (!$soapResult) {
 1228             $result=array();
 1229         } else {
 1230             $result=(array)$soapResult;
 1231         }
 1232         return  $result;
 1233     }
 1234     function GetFolderList() {
 1235         debugLog('Groupe::GetFolderList()');
 1236         $folders = array();
 1237         foreach ($this->_GroupeFolders as $val) {
 1238             $folder = $this->StatFolder($val);
 1239             if ($folder) {
 1240                 $folders[]=$folder;
 1241             }
 1242         }
 1243         $mailFolders=$this->_soap->call('getActiveSyncMailFolders',array($this->_devid));
 1244         foreach ($mailFolders as $val) {
 1245             $this->_mailFolders[$val->Box]=$val;
 1246             $folder = $this->StatFolder($val->Box);
 1247             if ($folder) {
 1248                 $folders[]=$folder;
 1249             }
 1250         }
 1251 
 1252         return $folders;
 1253     }
 1254 
 1255     function GetFolder($id) {
 1256         debugLog('Groupe::GetFolder('.$id.')');
 1257         $folder = new SyncFolder();
 1258         $folder->serverid = $id;
 1259         switch($id) {
 1260             case "VIRTUAL/calendar":
 1261                 $folder->parentid ="0";
 1262                 $folder->displayname = "Calendar";
 1263                 $folder->type = SYNC_FOLDER_TYPE_APPOINTMENT;
 1264             break;
 1265             case "VIRTUAL/contacts":
 1266                 $folder->parentid ="0";
 1267                 $folder->displayname = "Contacts";
 1268                 $folder->type = SYNC_FOLDER_TYPE_CONTACT;
 1269             break;
 1270             case "VIRTUAL/tasks":
 1271                 $folder->parentid ="0";
 1272                 $folder->displayname = "Tasks";
 1273                 $folder->type = SYNC_FOLDER_TYPE_TASK;
 1274             break;
 1275             default:
 1276                 if (isset($this->_mailFolders[$id])) {
 1277                     $folder->parentid=$this->_mailFolders[$id]->ParentBox?$this->_mailFolders[$id]->ParentBox:'0';
 1278                     $folder->displayname=$this->_mailFolders[$id]->Name;
 1279                     switch($this->_mailFolders[$id]->Type) {
 1280                         case 'I':
 1281                             $folder->type = SYNC_FOLDER_TYPE_INBOX;
 1282                             //debugLog(print_r($folder,1));
 1283                         break;
 1284                         case 'T':
 1285                             $folder->type = SYNC_FOLDER_TYPE_WASTEBASKET;
 1286                             $this->_wasteID = $id;
 1287                         break;
 1288                         case 'S':
 1289                             $folder->type = SYNC_FOLDER_TYPE_SENTMAIL;
 1290                         break;
 1291                         case 'D':
 1292                             $folder->type = SYNC_FOLDER_TYPE_DRAFTS;
 1293                         break;
 1294                         default:
 1295                             $folder->type = SYNC_FOLDER_TYPE_USER_MAIL;
 1296                         break;
 1297                     }
 1298                     //debugLog($folder->displayname.':'.$folder->type);
 1299                 } else {
 1300                     return false;
 1301                 }
 1302             break;
 1303         }
 1304         //debugLog(print_r($folder,1));
 1305         return $folder;
 1306     }
 1307 
 1308     function StatFolder($id) {
 1309         debugLog('Groupe::StatFolder('.$id.')');
 1310         $stat = array();
 1311         $folder = $this->GetFolder($id);
 1312         if ($folder) {
 1313             $stat["id"] = $id;
 1314             $stat["parent"] = $folder->parentid;
 1315             $stat["mod"] = $folder->displayname;
 1316         }
 1317         return $stat;
 1318     }
 1319     function ChangeFolder($parent, $id, $displayname, $type) {
 1320         debugLog('Groupe::ChangeFolder('.$parent.', '.$id.', '.$displayname.', '.$type.')');
 1321         return false;
 1322     }
 1323     function DeleteFolder($parent, $id) {
 1324         debugLog('Groupe::DeleteFolder('.$parent.', '.$id.')');
 1325         return false;
 1326     }
 1327     function GetMessageList($folderid, $cutoffdate) {
 1328         debugLog('Groupe::GetMessageList('.$folderid.','.$cutoffdate.')');
 1329         $messages = array();
 1330         switch($folderid) {
 1331             case 'VIRTUAL/contacts':
 1332                 $messages=$this->_soap->call('getActiveSyncContacts',array($this->_devid));
 1333                 //debugLog(print_r($messages,1));
 1334             break;
 1335             case 'VIRTUAL/calendar':
 1336                 if (!intval($cutoffdate)) {
 1337                     $cutoffdate=time()-3600*24*30;
 1338                     debugLog('SetCutoffDate:'.$cutoffdate);
 1339                 }
 1340                 $messages=$this->_soap->call('getActiveSyncAppointments',array($this->_devid,intval($cutoffdate)));
 1341                 //debugLog(var_export($messages,1));
 1342             break;
 1343             case 'VIRTUAL/tasks':
 1344                 if (!intval($cutoffdate)) {
 1345                     $cutoffdate=time()-3600*24*30;
 1346                     debugLog('SetCutoffDate:'.$cutoffdate);
 1347                 }
 1348                 $messages=$this->_soap->call('getActiveSyncTasks',array($this->_devid,intval($cutoffdate)));
 1349                 //debugLog(print_r($messages,1));
 1350             break;
 1351             default:
 1352                 if (!intval($cutoffdate)) {
 1353                     $cutoffdate=time()-3600*24*30;
 1354                     debugLog('SetCutoffDate:'.$cutoffdate);
 1355                 }
 1356                 $messages=$this->_soap->call('getActiveSyncMail',array($folderid,intval($cutoffdate),$this->_mailLimit));
 1357                 //debugLog(print_r($messages,1));
 1358             break;
 1359         }
 1360         $this->_statMessages[$folderid]=array();
 1361         foreach($messages as $v) {
 1362              $this->_statMessages[$folderid][$v['id']]=$v;
 1363         }
 1364         return $messages;
 1365     }
 1366 
 1367     function StatMessage($folderid, $id) {
 1368         debugLog('Groupe::StatMessage('.$folderid.', '.$id.')');
 1369         if (!isset($this->_statMessages[$folderid][$id])) {
 1370             $this->loadMessage($folderid,$id);
 1371         }
 1372         if (isset($this->_statMessages[$folderid][$id])) {
 1373             return $this->_statMessages[$folderid][$id];
 1374         }
 1375         return false;
 1376     }
 1377     function LoadMessage($folderid, $id, $mimesupport = 0) {
 1378         debugLog('Groupe::LoadMessage('.$folderid.', '.$id.', '.$mimesupport.')');
 1379         switch($folderid) {
 1380             case 'VIRTUAL/contacts':
 1381                 $this->_messages[$folderid][$id]=$this->_soap->call('getActiveSyncContactByID',array($id));
 1382                 if ($this->_messages[$folderid][$id]) {
 1383                     $this->_statMessages[$folderid][$id]=array(
 1384                         'id'=>$id,
 1385                         'mod'=>$this->_messages[$folderid][$id]->TimeModify,
 1386                         'flags'=>1,
 1387                         'acl'=>$this->_messages[$folderid][$id]->_acl,
 1388                     );
 1389                 }
 1390                 //debugLog(print_r($messages,1));
 1391             break;
 1392             case 'VIRTUAL/calendar':
 1393                 $this->_messages[$folderid][$id]=$this->_soap->call('getActiveSyncAppointmentByID',array($id));
 1394                 if ($this->_messages[$folderid][$id]) {
 1395                     $this->_statMessages[$folderid][$id]=array(
 1396                         'id'=>$id,
 1397                         'mod'=>$this->_messages[$folderid][$id]->TimeModify,
 1398                         'flags'=>1,
 1399                         'acl'=>$this->_messages[$folderid][$id]->_acl,
 1400                     );
 1401                 }
 1402                 //debugLog(print_r($this->_messages[$folderid][$id],1));
 1403             break;
 1404             case 'VIRTUAL/tasks':
 1405                 $this->_messages[$folderid][$id]=$this->_soap->call('getActiveSyncTaskByID',array($id));
 1406                 if ($this->_messages[$folderid][$id]) {
 1407                     $this->_statMessages[$folderid][$id]=array(
 1408                         'id'=>$id,
 1409                         'mod'=>$this->_messages[$folderid][$id]->TimeModify,
 1410                         'flags'=>1,
 1411                         'acl'=>$this->_messages[$folderid][$id]->_acl,
 1412                     );
 1413                 }
 1414                 //debugLog(print_r($messages,1));
 1415             break;
 1416             default:
 1417                 //debugLog('MemoryUsage BeforeLoad:'.number_format(memory_get_usage(true)/(1024*1024),2));
 1418                 $this->_messages[$folderid][$id]=$this->_soap->call('getActiveSyncMailMimeByID',array($folderid,$id));
 1419                 //debugLog('MemoryUsage AfterLoad:'.number_format(memory_get_usage(true)/(1024*1024),2));
 1420                 //debugLog('Groupe::LoadMessage: Result:'.substr(print_r($this->_messages[$folderid][$id],1),0,300));
 1421                 if ($this->_messages[$folderid][$id]) {
 1422                     $this->_statMessages[$folderid][$id]=array(
 1423                         'id'=>$id,
 1424                         'mod'=>$this->_messages[$folderid][$id]->Date,
 1425                         'flags'=>$this->_messages[$folderid][$id]->New?0:1,
 1426                         'olflags'=>0,
 1427                         'acl'=>7,
 1428                     );
 1429                 }
 1430             break;
 1431         }
 1432     }
 1433     function GetMessage($folderid, $id, $truncsize, $bodypreference=false, $optionbodypreference=false, $mimesupport = 0) {
 1434         debugLog('Groupe::GetMessage('.$folderid.', '.$id.','.$truncsize.','.$mimesupport.')');
 1435         switch($folderid) {
 1436             case 'VIRTUAL/contacts':
 1437                 if (!isset($this->_messages[$folderid][$id])) {
 1438                     $this->loadMessage($folderid,$id,$mimesupport);
 1439                 }
 1440                 if ($this->_messages[$folderid][$id]) {
 1441                     return  $this->_map['contact']->groupe2message($this->_messages[$folderid][$id], $truncsize, $bodypreference,$optionbodypreference, $mimesupport);
 1442                 }
 1443             break;
 1444             case 'VIRTUAL/calendar':
 1445                 if (!isset($this->_messages[$folderid][$id])) {
 1446                     $this->loadMessage($folderid,$id,$mimesupport);
 1447                 }
 1448                 if ($this->_messages[$folderid][$id]) {
 1449                     return  $this->_map['appointment']->groupe2message($this->_messages[$folderid][$id], $truncsize, $bodypreference,$optionbodypreference, $mimesupport);
 1450                 }
 1451             break;
 1452             case 'VIRTUAL/tasks':
 1453                 if (!isset($this->_messages[$folderid][$id])) {
 1454                     $this->loadMessage($folderid,$id,$mimesupport);
 1455                 }
 1456                 if ($this->_messages[$folderid][$id]) {
 1457                     return  $this->_map['task']->groupe2message($this->_messages[$folderid][$id], $truncsize, $bodypreference,$optionbodypreference, $mimesupport);
 1458                 }
 1459             break;
 1460             default:
 1461                 if (!isset($this->_messages[$folderid][$id])) {
 1462                     $this->loadMessage($folderid,$id, $mimesupport);
 1463                 }
 1464                 //debugLog('MemoryUsage BeforeDecode:'.number_format(memory_get_usage(true)/(1024*1024),2));
 1465                 if ($this->_messages[$folderid][$id]) {
 1466                     return  $this->_map['mail']->groupe2message($this->_messages[$folderid][$id], $truncsize, $bodypreference,$optionbodypreference, $mimesupport);
 1467                 }
 1468             break;
 1469          }
 1470         return false;
 1471     }
 1472 
 1473     function DeleteMessage($folderid, $id) {
 1474         debugLog('Groupe::DeleteMessage('.$folderid.', '.$id.')');
 1475         $stat=$this->StatMessage($folderid, $id);
 1476        // debugLog(print_r($stat,1));
 1477         if ($stat===false) {
 1478             debugLog('Message not exists:'.$id);
 1479             return true;
 1480         } elseif ($stat['acl']&4) {
 1481             switch($folderid) {
 1482                 case 'VIRTUAL/contacts':
 1483                     if ($id && $this->_soap->call('deleteActiveSyncContact',array($id))) {
 1484                         unset($this->_messages[$folderid][$id]);
 1485                         unset($this->_statMessages[$folderid][$id]);
 1486                         $this->_importedFolders[$folderid]['r']+=1;
 1487                         return true;
 1488                     }
 1489                 break;
 1490                 case 'VIRTUAL/calendar':
 1491                     if ($id && $this->_soap->call('deleteActiveSyncAppointment',array($id))) {
 1492                         unset($this->_messages[$folderid][$id]);
 1493                         unset($this->_statMessages[$folderid][$id]);
 1494                         $this->_importedFolders[$folderid]['r']+=1;
 1495                         return true;
 1496                     }
 1497                 break;
 1498                 case 'VIRTUAL/tasks':
 1499                     if ($id && $this->_soap->call('deleteActiveSyncTask',array($id))) {
 1500                         unset($this->_messages[$folderid][$id]);
 1501                         unset($this->_statMessages[$folderid][$id]);
 1502                         $this->_importedFolders[$folderid]['r']+=1;
 1503                         return true;
 1504                     }
 1505                 break;
 1506                 default:
 1507                     if ($id && $this->_soap->call('deleteMail',array($folderid,$id))) {
 1508                         unset($this->_messages[$folderid][$id]);
 1509                         unset($this->_statMessages[$folderid][$id]);
 1510                         $this->_importedFolders[$folderid]['r']+=1;
 1511                         return true;
 1512                     }
 1513                 break;
 1514             }
 1515         } else {
 1516             debugLog('NO DELETE Permissions:'.$id);
 1517         }
 1518         return false;
 1519     }
 1520 
 1521     function SetReadFlag($folderid, $id, $flags) {
 1522         debugLog('Groupe::SetReadFlag('.$folderid.','.$id.','.$flags.')');
 1523         if ($flags == 0) {
 1524             return $this->_soap->call('clearMailFlag',array($folderid,$id,"\\Seen"));
 1525         } else {
 1526             return $this->_soap->call('setMailFlag',array($folderid,$id,"\\Seen"));
 1527         }
 1528     }
 1529     function ChangeMessage($folderid, $id, $message) {
 1530         debugLog('Groupe::ChangeMessage('.$folderid.', '.$id.', ..)');
 1531         if ($id) {
 1532             $stat=$this->StatMessage($folderid, $id);
 1533         } else {
 1534             $stat=array('acl'=>7);
 1535         }
 1536         if ($stat['acl']&2) {
 1537             switch($folderid) {
 1538                 case 'VIRTUAL/contacts':
 1539                     if ($id && !isset($this->_messages[$folderid][$id])) {
 1540                         $this->loadMessage($folderid,$id);
 1541                     }
 1542                     if ($id && $this->_messages[$folderid][$id]) {
 1543                         $groupeMsg=$this->_messages[$folderid][$id];
 1544                         $mode='c';
 1545                     } else {
 1546                         $groupeMsg=(object)array();
 1547                         $mode='a';
 1548                     }
 1549                     $groupeMsg=$this->_map['contact']->message2groupe($message,$groupeMsg);
 1550                     $result=$this->_soap->call('updateActiveSyncContact',array($id,$groupeMsg));
 1551                     debugLog('updateActiveSyncContact:'.print_r($result,1));
 1552                     if (isset($result['error']) && $result['error']==0) {
 1553                         $this->_importedFolders[$folderid][$mode]+=1;
 1554                         if (!$result['reload'] && $result['id'] && isset($this->_messages[$folderid][$result['id']])) {
 1555                             unset($this->_messages[$folderid][$result['id']]);
 1556                             unset($this->_statMessages[$folderid][$result['id']]);
 1557                         }
 1558                         return $this->StatMessage($folderid, $result['id']);
 1559                     } else {
 1560                         return false;
 1561                     }
 1562                 break;
 1563                 case 'VIRTUAL/calendar':
 1564                     if ($id && !isset($this->_messages[$folderid][$id])) {
 1565                         $this->loadMessage($folderid,$id);
 1566                     }
 1567                     if ($id && $this->_messages[$folderid][$id]) {
 1568                         $groupeMsg=$this->_messages[$folderid][$id];
 1569                         $mode='c';
 1570                     } else {
 1571                         $groupeMsg=(object)array();
 1572                         $mode='a';
 1573                     }
 1574                     $groupeMsg=$this->_map['appointment']->message2groupe($message,$groupeMsg);
 1575                     //debugLog(print_r($groupeMsg,1));
 1576                     $result=$this->_soap->call('updateActiveSyncAppointment',array($id,$groupeMsg));
 1577                     debugLog('updateActiveSyncAppointment:'.print_r($result,1));
 1578                     if (isset($result['error']) && $result['error']==0) {
 1579                         $this->_importedFolders[$folderid][$mode]+=1;
 1580                         if (!$result['reload'] && $result['id'] && isset($this->_messages[$folderid][$result['id']])) {
 1581                             unset($this->_messages[$folderid][$result['id']]);
 1582                             unset($this->_statMessages[$folderid][$result['id']]);
 1583                         }
 1584                         return $this->StatMessage($folderid, $result['id']);
 1585                     } else {
 1586                         return false;
 1587                     }
 1588                 break;
 1589                 case 'VIRTUAL/tasks':
 1590                     if ($id && !isset($this->_messages[$folderid][$id])) {
 1591                         $this->loadMessage($folderid,$id);
 1592                     }
 1593                     if ($id && $this->_messages[$folderid][$id]) {
 1594                         $groupeMsg=$this->_messages[$folderid][$id];
 1595                         $mode='c';
 1596                     } else {
 1597                         $groupeMsg=(object)array();
 1598                         $mode='a';
 1599                     }
 1600                     $groupeMsg=$this->_map['task']->message2groupe($message,$groupeMsg);
 1601                     //debugLog(print_r($groupeMsg,1));
 1602                     $result=$this->_soap->call('updateActiveSyncTask',array($id,$groupeMsg));
 1603                     debugLog('updateActiveSyncTask:'.print_r($result,1));
 1604                     if (isset($result['error']) && $result['error']==0) {
 1605                         $this->_importedFolders[$folderid][$mode]+=1;
 1606                         if (!$result['reload'] && $result['id'] && isset($this->_messages[$folderid][$result['id']])) {
 1607                             unset($this->_messages[$folderid][$result['id']]);
 1608                             unset($this->_statMessages[$folderid][$result['id']]);
 1609                         }
 1610                         return $this->StatMessage($folderid, $result['id']);
 1611                     } else {
 1612                         return false;
 1613                     }
 1614                 break;
 1615             }
 1616         } else {
 1617             debugLog('NO CHANGE Permissions:'.$id);
 1618         }
 1619         return false;
 1620     }
 1621 
 1622     function MoveMessage($folderid, $id, $newfolderid) {
 1623         debugLog('Groupe::MoveMessage('.$folderid.', '.$id.', '.$newfolderid.')');
 1624         $stat=$this->StatMessage($folderid, $id);
 1625        // debugLog(print_r($stat,1));
 1626         if ($stat===false) {
 1627             debugLog('Message not exists:'.$id);
 1628             return true;
 1629         } elseif ($stat['acl']&2) {
 1630             switch($folderid) {
 1631                 case 'VIRTUAL/contacts':
 1632                 case 'VIRTUAL/calendar':
 1633                 case 'VIRTUAL/tasks':
 1634                     return false;
 1635                 break;
 1636                 default:
 1637                     if ($id && $newfolderid && $this->_soap->call('moveMail',array($folderid,$id,$newfolderid))) {
 1638                         unset($this->_messages[$folderid][$id]);
 1639                         unset($this->_statMessages[$folderid][$id]);
 1640                         $this->_importedFolders[$folderid]['r']+=1;
 1641                         return true;
 1642                     }
 1643                 break;
 1644             }
 1645         } else {
 1646             debugLog('NO MOVE Permissions:'.$id);
 1647         }
 1648         return false;
 1649     }
 1650     function GetAttachmentData($attname) {
 1651         debugLog('Groupe::GetAttachmentData('.$attname.')');
 1652         $data=explode(':',$attname);
 1653         $message=$this->_soap->call('getMailAttachment',$data);
 1654         if ($message!==false && $message['body']) {
 1655             print base64_decode($message['body']);
 1656             unset($message);
 1657             return true;
 1658         }
 1659         return false;
 1660     }
 1661     function ItemOperationsGetAttachmentData($attname) {
 1662         debugLog('Groupe::ItemOperationsGetAttachmentData('.$attname.')');
 1663         $data=explode(':',$attname);
 1664         $attachment = new SyncAirSyncBaseFileAttachment();
 1665         $message=$this->_soap->call('getMailAttachment',$data);
 1666         if ($message!==false && $message['body']) {
 1667             $attachment->_data = base64_decode($message['body']);
 1668             $attachment->total = strlen($message['body']);
 1669             $attachment->contenttype = trim($message['type']);
 1670         }
 1671         unset($message);
 1672         return $attachment;
 1673     }
 1674 
 1675     function SendMail($rfc822, $smartdata=array(), $protocolversion = false) {
 1676         debugLog("Groupe::SendMail: smartdata:".print_r($smartdata,1));
 1677         //debugLog("Groupe::SendMail: \n $rfc822" );
 1678         if (preg_match('@Content-Type:\s*text/calendar;\s*charset=[^;]+;\s*name=[a-z]+\.ics;\s*method=(REQUEST|REPLY)@i',$rfc822)) {
 1679             debugLog("Groupe::SendMail: Ignore Invitations");
 1680             return true;
 1681         }
 1682         if (preg_match('@Content-Type:\s*text/calendar;\s*charset=[^;]+;\s*method=(REQUEST|REPLY)@i',$rfc822)) {
 1683             debugLog("Groupe::SendMail: Ignore Invitations");
 1684             return true;
 1685         }
 1686 
 1687         $mailPlain='';
 1688         $mailHtml='';
 1689         $hdrs=array();
 1690 
 1691         $buildParams = array(
 1692             'eol' => "\n",
 1693             'charset' => 'utf-8',
 1694             'text_encoding' => 'base64',
 1695             'html_encoding' => 'base64',
 1696             'text_charset'  => 'utf-8',
 1697             'html_charset'  => 'utf-8',
 1698             'head_charset'  => 'utf-8',
 1699         );
 1700         $newMail = new Mail_mime($buildParams);
 1701         $newMail->setParam('text_charset','utf-8');
 1702 
 1703         $mimeParams = array(
 1704             'decode_headers' => true,
 1705             'decode_bodies' => true,
 1706             'include_bodies' => true,
 1707             'charset' => 'utf-8'
 1708         );
 1709         $mailObj = new Mail_mimeDecode($rfc822);
 1710         $mailMsg = $mailObj->decode($mimeParams);
 1711 
 1712 
 1713         foreach($mailMsg->headers as $k => $v) {
 1714             $k=strtolower($k);
 1715             if ($k == "sender") continue;
 1716             if ($k == "content-type") continue;
 1717             if ($k == "content-transfer-encoding") continue;
 1718             if ($k == "content-transfer-encoding") continue;
 1719             if ($k == "mime-version") continue;
 1720             // all other headers stay
 1721             $hdrs[ucfirst($k)]=trim($v);
 1722         }
 1723         debugLog("SendMail: parsed message headers: ". print_r($hdrs,1));
 1724         //debugLog("SendMail: parsed message: ". print_r($mailMsg,1));
 1725 
 1726         $this->combineMessage($mailMsg,$newMail,$mailPlain,$mailHtml,'new');
 1727         if (trim($mailHtml)) {
 1728             $mode='HTML';   
 1729         } else {
 1730             $mode='PLAIN';
 1731         }
 1732         debugLog("SendMail Format: ".$mode);
 1733         if (($smartdata['task'] == 'reply' || $smartdata['task'] == 'forward') && $smartdata['folderid'] && $smartdata['itemid']) {
 1734             if ($smartObj=$this->_soap->call('getActiveSyncMailMimeByID',array($smartdata['folderid'],$smartdata['itemid']))) {
 1735                 $origMime=array(base64_decode($smartObj->MimeHeader),base64_decode($smartObj->MimeBody));
 1736                 
 1737                 $mimeParams = array(
 1738                     'decode_headers' => true,
 1739                     'decode_bodies' => true,
 1740                     'include_bodies' => true,
 1741                     'charset' => 'utf-8'
 1742                 );
 1743                 $origObj = new Mail_mimeDecode($origMime);
 1744                 $origMsg = $origObj->decode($mimeParams);
 1745                 //debugLog("IMAP-SendMail: : parsed message Orig: ". print_r($origMsg,1));
 1746             
 1747                 $body_sep= "\r\n\r\n-----Original Message-----\r\n";
 1748                 if(isset($origMsg->headers['from'])) {
 1749                     $body_sep.= "From: " .$origMsg->headers['from']. "\r\n";
 1750                 }
 1751                 if(isset($origMsg->headers['to']) && strlen($origMsg->headers['to']) > 0) {
 1752                     $body_sep.= "To: " . $origMsg->headers['to'] . "\r\n";
 1753                 }
 1754                 if(isset($origMsg->headers['cc']) && strlen($origMsg->headers['cc']) > 0) {
 1755                     $body_sep.= "Cc: " . $origMsg->headers['cc'] . "\r\n";
 1756                 }
 1757                 if(isset($origMsg->headers['date'])) {
 1758                     $body_sep.= "Sent: " . $origMsg->headers['date'] . "\r\n";
 1759                 }
 1760                 if(isset($origMsg->headers['subject'])) {
 1761                     $body_sep.= "Subject: " . $origMsg->headers['subject'] . "\r\n";
 1762                 }
 1763                 $body_sep.="\r\n"."\r\n";
 1764                 $mailPlain.=$body_sep;
 1765                 
 1766                 if ($mode=='HTML') {
 1767                     $mailHtml.=nl2br($body_sep);
 1768                 }
 1769                 $this->combineMessage($origMsg,$newMail,$mailPlain,$mailHtml,$smartdata['task']);
 1770                 //debugLog("IMAP-SendMail: new Message Smart mailPlain: ".$mailPlain);
 1771                 //debugLog("IMAP-SendMail: new Message Smart mailHtml: ".$mailHtml);
 1772                 //$mailHtml='';
 1773             }
 1774         }
 1775         $newMail->setTXTBody($mailPlain);
 1776         if ($mode=='HTML') {
 1777             $newMail->setHTMLBody($mailHtml);
 1778         }
 1779         $body = $newMail->getMessageBody();
 1780         $hdrs = $newMail->headers($hdrs);
 1781         //advanced debugging
 1782         debugLog("IMAP-SendMail: headers: ".print_r($hdrs,1));
 1783         //debugLog("IMAP-SendMail: body: $body");
 1784 
 1785         return $this->_soap->call('sendActiveSyncMail',array($hdrs,$body));
 1786     }
 1787     function combineMessage(&$mailMsg,&$newMail,&$mailPlain,&$mailHtml,$task='') {
 1788         $bodyHtml='';
 1789         $bodyPlain='';
 1790         
 1791         if($mailMsg->ctype_primary == "multipart" && ($mailMsg->ctype_secondary == "mixed" || $mailMsg->ctype_secondary == "alternative")) {
 1792             $mparts = $mailMsg->parts;
 1793             for($i=0; $i<count($mparts); $i++) {
 1794                 $part = $mparts[$i];
 1795                 // palm pre & iPhone send forwarded messages in another subpart which are also parsed
 1796                 if($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative"  || $part->ctype_secondary == "related")) {
 1797                     foreach($part->parts as $spart) {
 1798                         $mparts[] = $spart;
 1799                     }
 1800                     continue;
 1801                 }
 1802                 // standard body
 1803                 if($part->ctype_primary == "text" && $part->ctype_secondary == "plain" && isset($part->body) && (!isset($part->disposition) || $part->disposition != "attachment")) {
 1804                     $bodyPlain.=$part->body; // assume only one text body
 1805                 } elseif($part->ctype_primary == "text" && $part->ctype_secondary == "html" && isset($part->body) && (!isset($part->disposition) || $part->disposition != "attachment")) {
 1806                     // html body
 1807                     $bodyHtml.=nl2br(preg_replace("@>\s+<@", "><", $part->body));
 1808                 } elseif ($task!='reply') {
 1809                     if(isset($part->d_parameters['filename']))
 1810                         $attname = $part->d_parameters['filename'];
 1811                     else if(isset($part->ctype_parameters['name']))
 1812                         $attname = $part->ctype_parameters['name'];
 1813                     else if(isset($part->headers['content-description']))
 1814                         $attname = $part->headers['content-description'];
 1815                     else $attname = "unknown attachment";
 1816                     // any other type, store as attachment
 1817                     $newMail->addAttachment($part->body,$part->ctype_primary.'/'.$part->ctype_secondary,$attname,false);
 1818                 }
 1819             }
 1820         } elseif($mailMsg->ctype_primary == "text" && $mailMsg->ctype_secondary == "html") {
 1821             $bodyHtml.=nl2br(preg_replace("@>\s+<@", "><", $mailMsg->body));
 1822         } else {
 1823             $bodyPlain.=$mailMsg->body;
 1824         }
 1825         if (!trim($bodyPlain)) {    
 1826             $bodyPlain = preg_replace("/<br(\s+)?\/?>/i", "\n", $bodyHtml);
 1827             // remove css-style tags
 1828             $bodyPlain = preg_replace("/<style.*?<\/style>/is", "", $bodyHtml);
 1829             // remove all other html
 1830             $bodyPlain = strip_tags($bodyPlain);
 1831         }
 1832         if (!trim($bodyHtml)) {
 1833             $bodyHtml=nl2br($bodyPlain);
 1834         }
 1835         $mailPlain.=$bodyPlain;
 1836         $mailHtml.=$bodyHtml;
 1837     }   
 1838         
 1839     
 1840     static function getAttachmentsRecursive($message,&$export_msg) {
 1841 
 1842         if(!isset($message->ctype_primary)) return;
 1843 
 1844         if(isset($message->disposition)) {
 1845 //      debugLog(print_r($message->headers,true));
 1846 //      debugLog($message->ctype_primary." ".$message->ctype_secondary." ".(isset($message->ctype_parameters['charset']) ? trim($message->ctype_parameters['charset']) : ""));
 1847             if (isset($message->headers['content-id']) &&
 1848                 strtolower($message->disposition) == 'inline') {
 1849                 $export_msg->addHTMLImage(  $message->body,
 1850                         trim($message->headers['content-type']),
 1851                         trim($message->d_parameters['filename']),
 1852                         false,
 1853                         substr(trim($message->headers['content-id']),1,-1));
 1854             } else {
 1855                 $export_msg->addAttachment( $message->body,
 1856                         trim($message->ctype_primary)."/".trim($message->ctype_secondary),
 1857                         trim($message->d_parameters['filename']),
 1858                         false,
 1859                         trim($message->headers['content-transfer-encoding']),
 1860                         trim($message->disposition),
 1861                         (isset($message->ctype_parameters['charset']) ? trim($message->ctype_parameters['charset']) : ""));
 1862             }
 1863         }
 1864 
 1865         if(strcasecmp($message->ctype_primary,"multipart")==0 && isset($message->parts) && is_array($message->parts)) {
 1866             foreach($message->parts as $part) {
 1867                BackendGroupe::getAttachmentsRecursive($part,$export_msg);
 1868             }
 1869         }
 1870     }
 1871     static function setAttachmentsRecursive($msgid,$message,$output,$partno='0') {
 1872         if ($partno=='0') {
 1873             $mno='';
 1874             if (!isset($message->parts)) $partno='1';
 1875         } else $mno=$partno.'.';
 1876 
 1877         //debugLog('Part:'.print_r($message->headers,1));
 1878         if (isset($message->headers['content-id']) || (isset($message->disposition) && ($message->disposition == "attachment" || $message->disposition == "inline"))) {
 1879             if(isset($output->_mapping['POOMMAIL:Attachments'])) {
 1880                 $attachment = new SyncAttachment();
 1881             } else if(isset($output->_mapping['AirSyncBase:Attachments'])) {
 1882                 $attachment = new SyncAirSyncBaseAttachment();
 1883             }
 1884             if (isset($message->body)) {
 1885                 $attachment->attsize = strlen($message->body);
 1886             }
 1887             if (isset($message->d_parameters['filename'])) {
 1888                 $attname = $message->d_parameters['filename'];
 1889             } elseif(isset($message->ctype_parameters['name'])) {
 1890                 $attname = $message->ctype_parameters['name'];
 1891             } elseif(isset($message->headers['content-description'])) {
 1892                 $attname = $message->headers['content-description'];
 1893             } else {
 1894                 $attname = "unknown attachment";
 1895             }
 1896             $attachment->displayname = w2u($attname);
 1897             $attachment->attmethod = 1;
 1898             $attachment->attoid = isset($message->headers['content-id']) ? trim($message->headers['content-id']) : "";
 1899             if ((isset($message->disposition) && $message->disposition == "inline") || isset($message->headers['content-id'])) {
 1900                 $attachment->isinline=true;
 1901                 $attachment->attmethod=6;
 1902                 //$attachment->contentid= isset($message->headers['content-id']) ? trim(substr($message->headers['content-id'],2,strlen($message->headers['content-id'])-3)) : "";
 1903                 $attachment->contentid= $attachment->attoid;
 1904                 $attachment->contenttype = trim($message->headers['content-type']);
 1905             } else {
 1906                 $attachment->attmethod=1;
 1907             }
 1908 
 1909             if (isset($output->_mapping['POOMMAIL:Attachments'])) {
 1910                 $attachment->attname =  $msgid . ":" . $partno;
 1911                 array_push($output->attachments, $attachment);
 1912             } else if(isset($output->_mapping['AirSyncBase:Attachments'])) {
 1913                 $attachment->attname =  $msgid . ":" . $partno;
 1914                 array_push($output->airsyncbaseattachments, $attachment);
 1915             }
 1916         }
 1917         //debugLog(print_r($message->ctype_primary,1));
 1918         //debugLog(print_r($message->parts,1));
 1919 
 1920         if(strcasecmp($message->ctype_primary,"multipart")==0 && isset($message->parts) && is_array($message->parts)) {
 1921             foreach($message->parts as $count=>$part) {
 1922                BackendGroupe::setAttachmentsRecursive($msgid,$part,$output,$mno.($count+1));
 1923             }
 1924         }
 1925 
 1926     }
 1927     /* Parse the message and return only the plaintext body
 1928      */
 1929     static function getBody($message) {
 1930         $body = "";
 1931         $htmlbody = "";
 1932 
 1933         BackendGroupe::getBodyRecursive($message, "plain", $body);
 1934 
 1935         if(!isset($body) || $body === "") {
 1936             BackendGroupe::getBodyRecursive($message, "html", $body);
 1937             // remove css-style tags
 1938             $body = preg_replace("/<style.*?<\/style>/is", "", $body);
 1939             // remove all other html
 1940             $body = strip_tags($body);
 1941         }
 1942 
 1943         return $body;
 1944     }
 1945 
 1946     // Get all parts in the message with specified type and concatenate them together, unless the
 1947     // Content-Disposition is 'attachment', in which case the text is apparently an attachment
 1948     static function getBodyRecursive($message, $subtype, &$body) {
 1949         if(!isset($message->ctype_primary)) return;
 1950         if(strcasecmp($message->ctype_primary,"text")==0 && strcasecmp($message->ctype_secondary,$subtype)==0 && isset($message->body))
 1951             $body .= $message->body;
 1952 
 1953         if(strcasecmp($message->ctype_primary,"multipart")==0 && isset($message->parts) && is_array($message->parts)) {
 1954             foreach($message->parts as $part) {
 1955                 if(!isset($part->disposition) || strcasecmp($part->disposition,"attachment"))  {
 1956                     BackendGroupe::getBodyRecursive($part, $subtype, $body);
 1957                 }
 1958             }
 1959         }
 1960     }
 1961     function enc_multipart($boundary, $body, $body_ct, $body_cte) {
 1962         $mail_body = "This is a multi-part message in MIME format\n\n";
 1963         $mail_body .= "--$boundary\n";
 1964         $mail_body .= "Content-Type: $body_ct\n";
 1965         $mail_body .= "Content-Transfer-Encoding: $body_cte\n\n";
 1966         $mail_body .= "$body\n\n";
 1967 
 1968         return $mail_body;
 1969     }
 1970 
 1971 
 1972     function enc_attach_file($boundary, $filenm, $filesize, $file_cont, $content_type = "") {
 1973         if (!$content_type) $content_type = "text/plain";
 1974         $mail_body = "--$boundary\n";
 1975         $mail_body .= "Content-Type: $content_type; name=\"$filenm\"\n";
 1976         $mail_body .= "Content-Transfer-Encoding: base64\n";
 1977         $mail_body .= "Content-Disposition: attachment; filename=\"$filenm\"\n";
 1978         $mail_body .= "Content-Description: $filenm\n\n";
 1979         $mail_body .= base64_encode($file_cont) . "\n\n";
 1980 
 1981         return $mail_body;
 1982     }
 1983     function GetWasteBasket() {
 1984         /*
 1985          * debugLog('Groupe::GetWasteBasket');
 1986          * return $this->_wasteID;
 1987         */
 1988         return false;
 1989     }
 1990 
 1991 
 1992    function GetHierarchyImporter() {
 1993        debugLog('Groupe::GetHierarchyImporter()');
 1994        return new ImportHierarchyChangesDiff($this);
 1995     }
 1996 
 1997     function GetContentsImporter($folderid) {
 1998         debugLog('Groupe::GetContentsImporter('.$folderid.')');
 1999         $this->_importedFolders[$folderid] = array(
 2000             'r'=>0,
 2001             'a'=>0,
 2002             'c'=>0,
 2003         );
 2004         return new ImportContentsChangesDiff($this, $folderid);
 2005     }
 2006 
 2007     function GetExporter($folderid = false) {
 2008         debugLog('Groupe::GetExporter('.$folderid.')');
 2009         return new ExportChangesDiff($this, $folderid);
 2010     }
 2011 
 2012     function GetHierarchy() {
 2013         debugLog('Groupe::GetHierarchy()');
 2014         $folders = array();
 2015 
 2016         $fl = $this->getFolderList();
 2017         foreach($fl as $f){
 2018             $folders[] = $this->GetFolder($f['id']);
 2019         }
 2020 
 2021         return $folders;
 2022     }
 2023 
 2024     function Fetch($folderid, $id, $bodypreference=false, $optionbodypreference=false, $mimesupport = 0) {
 2025         debugLog('Groupe::Fetch('.$folderid.','.$id.','.$mimesupport.')');
 2026         return $this->GetMessage($folderid, $id, 1024*1024,$bodypreference,$optionbodypreference, $mimesupport); // Forces entire message (up to 1Mb)
 2027     }
 2028     function MeetingResponse($requestid, $folderid, $error, &$calendarid) {
 2029         debugLog('Groupe::MeetingResponse('.$requestid.','.$folderid.','.$error.','.$calendarid.')');
 2030         return false;
 2031     }
 2032 
 2033     function getTruncSize($truncation) {
 2034         debugLog('Groupe::getTruncSize('.$truncation.')');
 2035         switch($truncation) {
 2036             case SYNC_TRUNCATION_HEADERS:
 2037                 return 0;
 2038             case SYNC_TRUNCATION_512B:
 2039                 return 512;
 2040             case SYNC_TRUNCATION_1K:
 2041                 return 1024;
 2042             case SYNC_TRUNCATION_5K:
 2043                 return 5*1024;
 2044             case SYNC_TRUNCATION_SEVEN:
 2045             case SYNC_TRUNCATION_ALL:
 2046                 return 1024*1024; // We'll limit to 1MB anyway
 2047             default:
 2048                 return 1024; // Default to 1Kb
 2049         }
 2050     }
 2051 
 2052     /**
 2053      * Returns array of items which contain contact information
 2054      *
 2055      * @param string $searchquery
 2056      *
 2057      * @return array
 2058      */
 2059     function getSearchResults($searchquery,$searchname) {
 2060         debugLog('Groupe::getSearchResults('.$searchquery.','.$searchname.')');
 2061         return false;
 2062     }
 2063 
 2064     function CheckPolicy($policykey, $devid) {
 2065         global $user, $auth_pw;
 2066 
 2067         $status = SYNC_PROVISION_STATUS_SUCCESS;
 2068 
 2069         $user_policykey = $this->getPolicyKey($user, $auth_pw, $devid);
 2070 
 2071         if ($user_policykey != $policykey) {
 2072             $status = SYNC_PROVISION_STATUS_POLKEYMISM;
 2073         }
 2074 
 2075         if (!$policykey) $policykey = $user_policykey;
 2076         return $status;
 2077     }
 2078 
 2079     /**
 2080      * Return a policy key for given user with a given device id.
 2081      * If there is no combination user-deviceid available, a new key
 2082      * should be generated.
 2083      *
 2084      * @param string $user
 2085      * @param string $pass
 2086      * @param string $devid
 2087      *
 2088      * @return unknown
 2089      */
 2090     function getPolicyKey($user, $pass, $devid) {
 2091         if($this->_loggedin === false) {
 2092             debugLog("logon failed for user $user");
 2093             return false;
 2094         }
 2095         $this->_device_filename = STATE_DIR . '/' . strtolower($devid) . '/device_info_'.$devid;
 2096 
 2097         if (file_exists($this->_device_filename)) {
 2098             $this->_device_info = unserialize(file_get_contents($this->_device_filename));
 2099             if (isset($this->_device_info['policy_key'])) {
 2100                 return $this->_device_info['policy_key'];
 2101             } else {
 2102                 return $this->setPolicyKey(0, $devid);
 2103             }
 2104         } else {
 2105             return $this->setPolicyKey(0, $devid);
 2106         }
 2107         return false;
 2108     }
 2109 
 2110     /**
 2111      * Generate a random policy key. Right now it's a 10-digit number.
 2112      *
 2113      * @return unknown
 2114      */
 2115     function generatePolicyKey() {
 2116 //      AS14 transmit Policy Key in URI on MS Phones.
 2117 //      In the base64 encoded binary string only 4 Bytes being reserved for
 2118 //      policy key and works in signed mode... Thats why we need here the max...
 2119 //      return mt_rand(1000000000, 9999999999);
 2120         return mt_rand(1000000000, 2147483647);
 2121     }
 2122 
 2123     /**
 2124      * Set a new policy key for the given device id.
 2125      *
 2126      * @param string $policykey
 2127      * @param string $devid
 2128      * @return unknown
 2129      */
 2130     function setPolicyKey($policykey, $devid) {
 2131         $this->_device_filename = STATE_DIR . '/' . strtolower($devid) . '/device_info_'.$devid;
 2132         // create device directory, if not yet existing
 2133         if (!file_exists(dirname($this->_device_filename)))
 2134         {
 2135             mkdir(dirname($this->_device_filename),0700,true);
 2136         }
 2137 
 2138         if($this->_loggedin !== false) {
 2139             if (!$policykey)
 2140                 $policykey = $this->generatePolicyKey();
 2141             $this->_device_info['policy_key'] = $policykey;
 2142             file_put_contents($this->_device_filename,serialize($this->_device_info));
 2143             return $policykey;
 2144         }
 2145         return false;
 2146     }
 2147 
 2148     /**
 2149      * Return a device wipe status
 2150      *
 2151      * @param string $user
 2152      * @param string $pass
 2153      * @param string $devid
 2154      * @return int
 2155      */
 2156     function getDeviceRWStatus($user, $pass, $devid) {
 2157         debugLog('Groupe::getDeviceRWStatus('.$user.',***,'.$devid.')');
 2158         if (!empty($this->_deviceProperties) || $this->Logon($user, "", $pass)) {
 2159             if (empty($this->_deviceProperties)) $this->_deviceProperties=$this->getDeviceProperties($this->_devid);
 2160             if (isset($this->_deviceProperties['RwStatus'])) {
 2161                 return $this->_deviceProperties['RwStatus'];
 2162             } else {
 2163                 return SYNC_PROVISION_RWSTATUS_NA;
 2164             }
 2165         }
 2166         return false;
 2167     }
 2168 
 2169     /**
 2170      * Set a new rw status for the device
 2171      *
 2172      * @param string $user
 2173      * @param string $pass
 2174      * @param string $devid
 2175      * @param string $status
 2176      *
 2177      * @return boolean
 2178      */
 2179     function setDeviceRWStatus($user, $pass, $devid, $status) {
 2180         debugLog('Groupe::setDeviceRWStatus('.$user.',***,'.$devid.','.$status.')');
 2181         if (!empty($this->_deviceProperties) || $this->Logon($user, "", $pass)) {
 2182             if (empty($this->_deviceProperties)) $this->_deviceProperties=$this->getDeviceProperties($this->_devid);
 2183             $this->_deviceProperties['RwStatus']=$status;
 2184             if ($this->_soap->call('setActiveSyncDevicePoperties',array($devid,(object)$this->_deviceProperties))) {
 2185                 return true;
 2186             }
 2187         }
 2188         return false;
 2189     }
 2190     function setLastSyncTime () {
 2191        debugLog('Groupe::setLastSyncTime()');
 2192         if (!empty($this->_deviceProperties)) {
 2193             $this->_deviceProperties['LastSync']=time();
 2194             if ($this->_soap->call('setActiveSyncDevicePoperties',array($this->_devid,(object)$this->_deviceProperties))) {
 2195                 return true;
 2196             }
 2197        }
 2198     }
 2199 
 2200     function setSettings($request,$devid) {
 2201         if (isset($request["oof"])) {
 2202             if ($request["oof"]["oofstate"] == 1) {
 2203                 // in case oof should be switched on do it here
 2204                 // store somehow your oofmessage in case your system supports.
 2205                 // response["oof"]["status"] = true per default and should be false in case
 2206                 // the oof message could not be set
 2207                 $response["oof"]["status"] = true;
 2208             } else {
 2209                 // in case oof should be switched off do it here
 2210                 $response["oof"]["status"] = true;
 2211             }
 2212         }
 2213         if (isset($request["deviceinformation"])) {
 2214             //error_log(print_r($request["deviceinformation"]));
 2215             // in case you'd like to store device informations do it here.
 2216             $response["deviceinformation"]["status"] = true;
 2217         }
 2218         if (isset($request["devicepassword"])) {
 2219             // in case you'd like to store device informations do it here.
 2220             $response["devicepassword"]["status"] = true;
 2221         }
 2222 
 2223         return $response;
 2224     }
 2225 
 2226     function getSettings ($request,$devid)  {
 2227         if (isset($request["userinformation"])) {
 2228             $response["userinformation"]["status"] = 1;
 2229             //$response["userinformation"]["emailaddresses"][] = $GLOBALS['egw_info']['user']['email'];
 2230         } else {
 2231             $response["userinformation"]["status"] = false;
 2232         }
 2233         if (isset($request["oof"])) {
 2234             $response["oof"]["status"]  = 0;
 2235         }
 2236         return $response;
 2237     }
 2238 
 2239     function AlterPing($folderid='') {
 2240         debugLog('Groupe::AlterPing('.$folderid.')');
 2241         if ($folderid) {
 2242             switch($folderid) {
 2243                 case 'VIRTUAL/contacts':
 2244                 case 'VIRTUAL/calendar':
 2245                 case 'VIRTUAL/tasks':
 2246 
 2247                     break;
 2248                 default:
 2249                     /*
 2250                     return true;
 2251                     */
 2252                 break;
 2253             }
 2254         }
 2255         return false;
 2256     }
 2257 
 2258     function AlterPingChanges($folderid, &$syncstate) {
 2259         debugLog('Groupe::AlterPingChanges('.$folderid.','.$syncstate.')');
 2260         switch($folderid) {
 2261             case 'VIRTUAL/contacts':
 2262             case 'VIRTUAL/calendar':
 2263             case 'VIRTUAL/tasks':
 2264 
 2265             break;
 2266             default:
 2267                 /*if ($folderid) {
 2268                     $status=$this->_soap->call('statMailBox',array($folderid));
 2269                     if (!$status) {
 2270                         debugLog("AlterPingChanges: could not stat folder $folderid");
 2271                         return false;
 2272                     }
 2273                     else {
 2274                         $newstate = "M:". $status->NumMsg ."-R:". $status->NumRec ."-U:". $status->NextUid;
 2275                         if ($syncstate!=$newstate) {
 2276                             $syncstate = $newstate;
 2277                             debugLog("AlterPingChanges: Change FOUND!");
 2278                             // build a dummy change
 2279                             return array(array("type" => "fakeChange"));
 2280                         }
 2281                     }
 2282                 }*/
 2283             break;
 2284         }
 2285         return array();
 2286     }
 2287 
 2288 
 2289     function escape($data){
 2290         if (is_array($data)) {
 2291             foreach ($data as $key => $val) {
 2292                 $data[$key] = $this->escape($val);
 2293             }
 2294             return $data;
 2295         }
 2296         $data = str_replace("\r\n", "\n", $data);
 2297         $data = str_replace("\r", "\n", $data);
 2298         $data = str_replace(array('\\', ';', ',', "\n"), array('\\\\', '\\;', '\\,', '\\n'), $data);
 2299         return u2wi($data);
 2300     }
 2301 
 2302     function unescape($data){
 2303         $data = str_replace(array('\\\\', '\\;', '\\,', '\\n','\\N'),array('\\', ';', ',', "\n", "\n"),$data);
 2304         return $data;
 2305     }
 2306 
 2307 
 2308 };
 2309 class SoapHeaderUsernameToken {
 2310     public $Password;
 2311     public $Username;
 2312     public function __construct($l, $p) {
 2313         $this->Password = $p;
 2314         $this->Username = $l;
 2315     }
 2316 }
 2317 class GroupeSoapClient {
 2318     private $_soapClient;
 2319     public function __construct() {
 2320         if (defined('GROUP_URL_DOMAIN') && GROUP_URL_DOMAIN) {
 2321             $location=GROUP_URL_DOMAIN.GROUP_URL_PATH;
 2322         } else {
 2323             $location=((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])?'https://':'http://').$_SERVER['SERVER_NAME'].GROUP_URL_PATH;
 2324         }
 2325         debugLog('Groupe::InitSoap: '.$location);
 2326         $this->_soapClient = new SoapClient(null,array(
 2327             'location' => $location,
 2328             'uri'      => "http://localhost/SoapServer/",
 2329             //'trace'=>true,
 2330         ));
 2331     }
 2332     public function initUser($username,$password) {
 2333         $UsernameToken = new SoapHeaderUsernameToken($username, $password);
 2334         $soapHeaders[] = new SoapHeader('http://schemas.xmlsoap.org/ws/2002/07/utility', 'UsernameToken', $UsernameToken);
 2335         $this->_soapClient->__setSoapHeaders($soapHeaders);
 2336     }
 2337     public function call($function,$params=array()) {
 2338         try {
 2339             return $this->_soapClient->__soapCall($function, $params);
 2340         } catch (Exception $e) {
 2341             debugLog(print_r($e,1));
 2342             $this->debug();
 2343         }
 2344     }
 2345     public function debug() {
 2346         //debugLog(print_r($this->_soapClient->__getLastRequest(),1));
 2347         //debugLog(print_r($this->_soapClient->__getLastResponseHeaders(),1));
 2348         //debugLog(print_r($this->_soapClient->__getLastResponse(),1));
 2349     }
 2350 }
 2351 
 2352 ?>