source: trunk/zpush/backend/expresso/providers/calendarProvider.php @ 8131

Revision 8131, 54.0 KB checked in by cristiano, 11 years ago (diff)

Ticket #3209 - Integrar módulo de sincronização Z-push ao Expresso

Line 
1<?php
2
3require_once __DIR__ . '/../../../lib/default/diffbackend/diffbackend.php';
4require_once EXPRESSO_PATH . '/prototype/api/controller.php';
5require_once EXPRESSO_PATH . '/prototype/api/config.php';
6require_once EXPRESSO_PATH . '/prototype/modules/calendar/constants.php';
7
8use prototype\api\Config as Config;
9
10class ExpressoCalendarProvider extends BackendDiff
11{
12
13    var $_uidnumber;
14
15    function __construct()
16    {
17
18    }
19
20    /**
21     * Returns a list (array) of folders, each entry being an associative array
22     * with the same entries as StatFolder(). This method should return stable information; ie
23     * if nothing has changed, the items in the array must be exactly the same. The order of
24     * the items within the array is not important though.
25     *
26     * @access protected
27     * @return array/boolean        false if the list could not be retrieved
28     */
29    public function GetFolderList()
30    {
31        $return = array();
32        $criteria = CALENDAR_SYNC_SIGNED_CALENDARS ? array( 'filter' => array( 'AND' , array( '=' , 'type' , '0' ) , array( '=' , 'user' , $this->_uidnumber ))) : array( 'filter' => array ( 'AND'  ,array( '=' , 'isOwner' , '1' ),array( '=' , 'type' , '0' ) , array( '=' , 'user' , $this->_uidnumber )));
33        $sigs = Controller::find(array('concept' => 'calendarSignature'), array( 'id','calendar' ), $criteria);
34
35        if(Request::GetDeviceType()  == 'iPhone' || Request::GetDeviceType()  == 'iPad')
36        {
37            foreach($sigs as $sig)
38            {
39                $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
40                $tmpSig = array();
41                $tmpSig["id"] = 'calendar'.$sig['id'];
42                $tmpSig["parent"] = 0;
43                $tmpSig["mod"] = $calendar['name'];
44                $return[] = $tmpSig;
45            }
46        }
47        else
48        {
49            $defaultCalendar = Controller::find(array('concept' => 'modulePreference'), array('value','id') , array('filter' => array( 'and' , array('=' , 'name' , 'defaultCalendar') , array('=' , 'module' , 'expressoCalendar') , array('=' , 'user' , $this->_uidnumber )  )) );
50
51            if(isset($defaultCalendar[0])) //Prioriza agenda default de importação pois o android so sincroniza a primeira agenda.
52            {
53                foreach($sigs as $i => $sig)
54                {
55                    if($sig['calendar'] == $defaultCalendar[0]['value'])
56                    {
57                        $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
58                        $tmpSig = array();
59                        $tmpSig["id"] = 'calendar'.$sig['id'];
60                        $tmpSig["parent"] = 0;
61                        $tmpSig["mod"] = $calendar['name'];
62                        $return[] = $tmpSig;
63                    }
64                }
65            }
66            else
67            {
68                $sig = $sigs[0];
69                $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
70                $tmpSig = array();
71                $tmpSig["id"] = 'calendar'.$sig['id'];
72                $tmpSig["parent"] = 0;
73                $tmpSig["mod"] = $calendar['name'];
74                $return[] = $tmpSig;
75
76            }
77        }
78
79        return $return;
80    }
81
82    /**
83     * Returns an actual SyncFolder object with all the properties set. Folders
84     * are pretty simple, having only a type, a name, a parent and a server ID.
85     *
86     * @param string        $id           id of the folder
87     *
88     * @access public
89     * @return object   SyncFolder with information
90     */
91    public function GetFolder($id)
92    {
93        $idNumber = (int)str_replace('calendar' , '' , $id);
94
95        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
96        $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
97
98        if(is_array($calendarSignature) && count($calendarSignature) > 0 )
99        {
100            $folder = new SyncFolder();
101            $folder->serverid = $id;
102            $folder->parentid = "0";
103            $folder->displayname = $calendar['name'];
104            $folder->type = SYNC_FOLDER_TYPE_APPOINTMENT;
105            return $folder;
106        }
107
108        return false;
109    }
110
111    /**
112     * Returns folder stats. An associative array with properties is expected.
113     *
114     * @param string        $id             id of the folder
115     *
116     * @access public
117     * @return array
118     *          Associative array(
119     *              string  "id"            The server ID that will be used to identify the folder. It must be unique, and not too long
120     *                                      How long exactly is not known, but try keeping it under 20 chars or so. It must be a string.
121     *              string  "parent"        The server ID of the parent of the folder. Same restrictions as 'id' apply.
122     *              long    "mod"           This is the modification signature. It is any arbitrary string which is constant as long as
123     *                                      the folder has not changed. In practice this means that 'mod' can be equal to the folder name
124     *                                      as this is the only thing that ever changes in folders. (the type is normally constant)
125     *          )
126     */
127    public function StatFolder($id)
128    {
129        $return = array();
130        $idNumber = (int)str_replace('calendar' , '' , $id);
131        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
132        $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
133
134        $return["id"] = $id;
135        $return["parent"] = 0;
136        $return["mod"] = $calendar['name'];
137
138        return $return;
139    }
140
141    /**
142     * Creates or modifies a folder
143     *
144     * @param string        $folderid       id of the parent folder
145     * @param string        $oldid          if empty -> new folder created, else folder is to be renamed
146     * @param string        $displayname    new folder name (to be created, or to be renamed to)
147     * @param int           $type           folder type
148     *
149     * @access public
150     * @return boolean                      status
151     * @throws StatusException              could throw specific SYNC_FSSTATUS_* exceptions
152     *
153     */
154    public function ChangeFolder($folderid, $oldid, $displayname, $type)
155    {
156        if($oldid)
157        {
158            $idNumber = (int)str_replace('calendar' , '' , $oldid);
159            $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
160
161            Controller::update( array('concept' => 'calendar' , 'id' => $calendarSignature['calendar']), array( 'name' => $displayname) );
162
163            return $this->StatFolder($oldid);
164        }
165        else
166        {
167             $cal = array('name' => $displayname,
168                'timezone' => 'America/Sao_Paulo',
169                'type' => '0'
170            );
171
172            $calCreated = Controller::create(array('concept' => 'calendar'), $cal);
173
174            if(!$calCreated){
175                return false;
176            }
177
178            $sig = array('user' => $_SESSION['wallet']['user']['uidNumber'],
179                'calendar' => $calCreated['id'],
180                'isOwner' => '1',
181                'dtstamp' => time() . '000',
182                'fontColor' => 'FFFFFF',
183                'backgroundColor' => '3366CC',
184                'borderColor' => '3366CC',
185            );
186
187            $sigCreated = Controller::create(array('concept' => 'calendarSignature'), $sig);
188
189            if(!$sigCreated){
190                return false;
191            }
192            else
193            {
194                $return = array();
195                $return["id"] = 'calendar'.$calCreated;
196                $return["parent"] = 0;
197                $return["mod"] = $displayname;
198                return $return;
199            }
200        }
201
202        return false;
203
204    }
205
206    /**
207     * Deletes a folder
208     *
209     * @param string        $id
210     * @param string        $parent         is normally false
211     *
212     * @access public
213     * @return boolean                      status - false if e.g. does not exist
214     * @throws StatusException              could throw specific SYNC_FSSTATUS_* exceptions
215     */
216    public function DeleteFolder($id, $parent)
217    {
218        $interation = array();
219        $idNumber = (int)str_replace('calendar' , '' , $id);
220        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
221
222        $interation['calendar://' . $calendarSignature['calendar']] = false;
223        ob_start();
224        $args = $interation;
225        include EXPRESSO_PATH.'/prototype/Sync.php';
226        ob_end_clean();
227
228        return true;
229    }
230
231    /**
232     * Returns a list (array) of messages, each entry being an associative array
233     * with the same entries as StatMessage(). This method should return stable information; ie
234     * if nothing has changed, the items in the array must be exactly the same. The order of
235     * the items within the array is not important though.
236     *
237     * The $cutoffdate is a date in the past, representing the date since which items should be shown.
238     * This cutoffdate is determined by the user's setting of getting 'Last 3 days' of e-mail, etc. If
239     * the cutoffdate is ignored, the user will not be able to select their own cutoffdate, but all
240     * will work OK apart from that.
241     *
242     * @param string        $folderid       id of the parent folder
243     * @param long          $cutoffdate     timestamp in the past from which on messages should be returned
244     *
245     * @access public
246     * @return array/false                  array with messages or false if folder is not available
247     */
248    public function GetMessageList($folderid, $cutoffdate)
249    {
250        $idNumber = (int)str_replace('calendar' , '' , $folderid);
251        $cal_ids = null;
252        $messages = array();
253
254        $sql = 'SELECT calendar_object.last_update , calendar_object.cal_uid FROM calendar_signature , calendar , calendar_to_calendar_object, calendar_object WHERE calendar_signature.id = '.$idNumber.' AND calendar_signature.calendar_id = calendar.id AND calendar_to_calendar_object.calendar_id = calendar.id AND calendar_to_calendar_object.calendar_object_id = calendar_object.id  AND calendar_object.last_update > '. $cutoffdate . '000';
255
256        $rs = Controller::service('PostgreSQL')->execSql($sql);
257
258        if(is_array($rs))
259        {
260            foreach($rs as $v)
261            {
262                $message = array();
263                $message["id"] = $v['cal_uid'];
264                $message["mod"] = substr($v['last_update'], 0, -3);
265                $message["flags"] = 1; // always 'read'
266                $messages[] = $message;
267            }
268        }
269
270        return $messages;
271    }
272
273    /**
274     * Returns the actual SyncXXX object type. The '$folderid' of parent folder can be used.
275     * Mixing item types returned is illegal and will be blocked by the engine; ie returning an Email object in a
276     * Tasks folder will not do anything. The SyncXXX objects should be filled with as much information as possible,
277     * but at least the subject, body, to, from, etc.
278     *
279     * @param string            $folderid           id of the parent folder
280     * @param string            $id                 id of the message
281     * @param ContentParameters $contentparameters  parameters of the requested message (truncation, mimesupport etc)
282     *
283     * @access public
284     * @return object/false                 false if the message could not be retrieved
285     */
286    public function GetMessage($folderid, $id, $contentparameters)
287    {
288        $idNumber = (int)str_replace('calendar' , '' , $folderid);
289        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
290
291        $schedulable = Controller::find(array('concept' => 'schedulable'), null , array('filter' => array( '=' , 'uid' , $id)));
292        if( is_array($schedulable) && count($schedulable) > 0 )
293
294            $schedulable = $schedulable[0];
295        else
296            return false;
297
298        $message = new SyncAppointment();
299        $message->uid = $id;
300        $message->dtstamp = (int) substr($schedulable['dtstamp'], 0, -3);
301        $message->starttime =  (int) substr($schedulable['startTime'], 0, -3);
302        $message->endtime = (int) substr($schedulable['endTime'], 0, -3);
303        $message->deleted = 0;
304
305        $message->subject = mb_convert_encoding($schedulable['summary'] , 'UTF-8' , 'UTF-8,ISO-8859-1');
306        $message->location =  mb_convert_encoding($schedulable['location'], 'UTF-8' , 'UTF-8,ISO-8859-1');
307
308        if(isset($schedulable['description']) && $schedulable['description'] != "") {
309            $message->body = mb_convert_encoding($schedulable['description'], 'UTF-8' , 'UTF-8,ISO-8859-1');  // phpgw_cal.description
310            $message->bodysize = strlen($message->body);
311            $message->bodytruncated = 0;
312        }
313
314        $message->sensitivity = 0; // 0 - Normal,
315        $message->alldayevent = (int)$schedulable['allDay']; // (0 - Não(default), 1- Sim)
316        $message->timezone = base64_encode($this->_getSyncBlobFromTZ($this->_getGMTTZ()));
317
318
319        /*
320         * Sincronização de participantes e organizador
321         */
322        $participants = Controller::find(array('concept' => 'participant'), null , array('deepness' => 1 , 'filter' => array( '=' , 'schedulable' , $schedulable['id'] )));
323        if(is_array($participants) && count($participants) > 0)
324        {
325            $message->attendees = array();
326            foreach($participants as $participant)
327            {
328                if($participant['isOrganizer'] == 1) //organizador
329                {
330                    $message->organizername = mb_convert_encoding($participant['user']['name'], 'UTF-8' , 'UTF-8,ISO-8859-1');
331                    $message->organizeremail = mb_convert_encoding($participant['user']['mail'], 'UTF-8' , 'UTF-8,ISO-8859-1');
332                }
333                else
334                {
335                    $attendee = new SyncAttendee();
336                    $attendee->name =  mb_convert_encoding($participant['user']['name'], 'UTF-8' , 'UTF-8,ISO-8859-1');
337                    $attendee->email = mb_convert_encoding($participant['user']['mail'], 'UTF-8' , 'UTF-8,ISO-8859-1');
338                    $message->attendees[] = $attendee;
339                }
340
341                if($participant['user']['id'] == $this->_uidnumber  )
342                {
343                    if($participant['isOrganizer'] == 1 || strpos($participant['acl'] ,'w') !== false) // Caso ele seja organizador ou tenha permisão de editar o evento
344                    {
345                        $message->meetingstatus = 0;
346                    }
347                    else
348                    {
349                        $message->meetingstatus = 3;
350                    }
351
352                    if(isset($participant['alarms'][0]) )
353                    {
354                        switch($participant['alarms'][0]['unit'])
355                        {
356                            case 'h':
357                                $mult = 60;
358                                break;
359                            case 'd':
360                                $mult = 3600;
361                                break;
362                            default:
363                                $mult = 1;
364                                break;
365                        }
366
367                        $message->reminder = $participant['alarms'][0]['time'] * $mult;
368                    }
369
370                    switch($participant['status'])
371                    {
372                        case STATUS_ACCEPTED:
373                            $message->busystatus = 2;
374                            break;
375                        case STATUS_TENTATIVE:
376                            $message->busystatus = 1;
377                            break;
378                        case STATUS_DECLINED:
379                            $message->busystatus = 3;
380                            break;
381                        case STATUS_UNANSWERED:
382                            $message->busystatus = 0;
383                            break;
384                    }
385
386                }
387            }
388        }
389        //------------------------------------------------------------------------------------------------------------//
390
391        /*
392        * Sincronização de Recorrência
393        */
394        $repeats = Controller::find(array('concept' => 'repeat'), null , array( 'filter' => array( 'and' , array( '=' , 'schedulable' , $schedulable['id'] ),array( '!=' , 'frequency' , 'none' )  ) ));
395        if(is_array($repeats) && count($repeats) > 0)
396        {
397            $repeat = $repeats[0];
398            $recur = new SyncRecurrence();
399
400            switch($repeat['frequency'])
401            {
402                case 'daily':
403                    $recur->type = 0;
404                    break;
405                case 'weekly':
406                    $recur->type = 1;
407                    break;
408                case 'monthly':
409                    $recur->type = 2;
410                    break;
411                case 'yearly':
412                    $recur->type = 5;
413                    break;
414            }
415
416            if($repeat['endTime'])
417                $recur->until =  (int) substr($repeat['endTime'], 0, -3);
418
419            $recur->interval = $repeat['interval'] ? $repeat['interval'] : 1;
420
421            if($repeat["count"])
422                $recur->occurrences = (int)$repeat["count"];
423
424            if($repeat["byweekno"])
425                $recur->weekofmonth = (int)$repeat["byweekno"];
426
427            if($repeat["bymonthday"])
428                $recur->dayofmonth = (int)$repeat["bymonthday"];
429
430
431            if($repeat["byday"])
432                $recur->dayofweek = $this->formatDoWeek($repeat["byday"]);
433
434            //$recurrence->monthofyear ; //Não implementado no expresso
435
436            $expetions = Controller::find(array('concept' => 'repeatOccurrence'), null , array( 'filter' => array( 'and' , array( '=' , 'exception' , '1' ),array( '=' , 'repeat' , $repeat['id'] ) )));
437            if(is_array($expetions) && count($expetions) > 0)
438            {
439                $message->exceptions = array();
440                foreach($expetions as $expetion)
441                {
442                    $exception = new SyncAppointmentException();
443                    $exception->exceptionstarttime =  (int) substr($expetion['occurrence'], 0, -3);
444                    $exception->deleted = '1';
445                    $message->exceptions[] = $exception;
446                }
447            }
448
449            $message->recurrence = $recur;
450        }
451
452
453        return $message;
454    }
455
456    /**
457     * Returns message stats, analogous to the folder stats from StatFolder().
458     *
459     * @param string        $folderid       id of the folder
460     * @param string        $id             id of the message
461     *
462     * @access public
463     * @return array or boolean if fails
464     *          Associative array(
465     *              string  "id"            Server unique identifier for the message. Again, try to keep this short (under 20 chars)
466     *              int     "flags"         simply '0' for unread, '1' for read
467     *              long    "mod"           This is the modification signature. It is any arbitrary string which is constant as long as
468     *                                      the message has not changed. As soon as this signature changes, the item is assumed to be completely
469     *                                      changed, and will be sent to the PDA as a whole. Normally you can use something like the modification
470     *                                      time for this field, which will change as soon as the contents have changed.
471     *          )
472     */
473    public function StatMessage($folderid, $id)
474    {
475        $sql = 'SELECT last_update , cal_uid FROM calendar_object WHERE cal_uid = \''.pg_escape_string($id) .'\'';
476        $message = array();
477
478        $rs = Controller::service('PostgreSQL')->execSql($sql);
479        if(is_array($rs))
480        {
481            $message["mod"] = substr($rs[0]['last_update'], 0, -3);
482            $message["id"] = $id;
483            $message["flags"] = 1;
484        }
485        return $message;
486    }
487
488    /**
489     * Called when a message has been changed on the mobile. The new message must be saved to disk.
490     * The return value must be whatever would be returned from StatMessage() after the message has been saved.
491     * This way, the 'flags' and the 'mod' properties of the StatMessage() item may change via ChangeMessage().
492     * This method will never be called on E-mail items as it's not 'possible' to change e-mail items. It's only
493     * possible to set them as 'read' or 'unread'.
494     *
495     * @param string        $folderid       id of the folder
496     * @param string        $id             id of the message
497     * @param SyncXXX       $message        the SyncObject containing a message
498     *
499     * @access public
500     * @return array                        same return value as StatMessage()
501     * @throws StatusException              could throw specific SYNC_STATUS_* exceptions
502     */
503    public function ChangeMessage($folderid, $idMessage, $message)
504    {
505
506        $idNumber = (int)str_replace('calendar' , '' , $folderid);
507        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
508        $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
509
510        if($idMessage)
511        {
512            $schedulable = Controller::find(array('concept' => 'schedulable'), null , array('deepness'=> 2 , 'filter' => array( '=' , 'uid' , $idMessage)));
513            $schedulable = $schedulable[0];
514
515
516            foreach($schedulable['participants'] as $i => $v)
517            {
518                if($v['user']['id'] == $this->_uidnumber )
519                {
520                    if(strpos($v['acl'] ,'w') !== false) //Caso o usuario tenha permissão de editar o evento
521                    {
522                        return  $this->updateEvent($folderid, $idMessage, $message , $calendar ,$schedulable);
523                    }
524                    else
525                    {
526                        $interation = array();
527
528                        if(isset($message->reminder) && $message->reminder > 0)
529                        {
530                            $alarm = array();
531                            $alarmID = mt_rand() . '6(Formatter)';
532                            $alarm['type'] = 'alert';
533                            $alarm['time'] = $message->reminder;
534                            $alarm['unit'] = 'm';
535                            $alarm['participant'] = $v['id'];
536                            $alarm['schedulable'] = $schedulable['id'];
537                            $interation['alarm://' . $alarmID ] = $alarm;
538
539                        }
540
541                        $status  = $this->formatBusy($message->busystatus);
542
543                        if($status == STATUS_DECLINED ) //Caso ele não seja dono do evento e recusou o convite deletar o evento da sua agenda.
544                        {
545                            Controller::deleteAll(array('concept' => 'calendarToSchedulable' ) , false , array('filter' => array('AND', array('=','calendar',$calendarSignature['calendar']), array('=','schedulable',$schedulable['id']))));
546                        }
547
548                        $v['status'] = $status;
549
550                        $interation['participant://' . $v['id'] ] = $v;
551
552                        ob_start();
553                        $args = $interation;
554                        include EXPRESSO_PATH.'/prototype/Sync.php';
555                        ob_end_clean();
556
557                    }
558                }
559            }
560            return $this->StatMessage($folderid, $message->uid);
561        }
562        else
563        {
564            if (!$schedulable = $this->_getSchedulable($message->uid))
565                return  $this->createEvent($folderid, $idMessage, $message ,$calendar);
566            else{
567                $links = Controller::read(array('concept' => 'calendarToSchedulable'), array('id'), array('filter' =>
568                array('AND',
569                    array('=', 'calendar', $calendar['id']),
570                    array('=', 'schedulable', $schedulable['id'])
571                )));
572
573                if(!$links &&  !isset($links[0]))
574                    Controller::create(array('concept' => 'calendarToSchedulable'), array('calendar' => $calendar['id'], 'schedulable' => $schedulable['id']));
575
576                foreach($schedulable['participants'] as $i => $v)
577                {
578                    if($v['user']['id'] == $this->_uidnumber)
579                    {
580                        Controller::update(array('concept' => 'participant','id' => $v['id']), array('status' => $this->formatBusy($message->busystatus ) ));
581                    }
582                }
583
584                return $this->StatMessage($folderid, $message->uid);
585            }
586        }
587
588    }
589
590    private function _getSchedulable($uid) {
591        $schedulable = Controller::find(array('concept' => 'schedulable'), false, array('filter' => array('=', 'uid', $uid), 'deepness' => 2));
592        return (isset($schedulable[0])) ? $schedulable[0] : false;
593    }
594
595    private function updateEvent($folderid, $idMessage, $message , $calendar ,$schedulable )
596    {
597
598
599        $tz_CEL = $this->_getTZFromSyncBlob(base64_decode($message->timezone));
600        $GMT_CEL = -(($tz_CEL["bias"] + $tz_CEL["dstbias"]) * 60);
601
602        $interation = array();
603        $eventID = $schedulable['id'];
604        $schedulable['uid'] = $message->uid;
605        $schedulable['summary'] = $message->subject;
606        $schedulable['location'] = $message->location;
607        $schedulable['class'] = 1;
608
609        /// Eliminana o timezone, enviado pelo ceulular e coloca no timezone do calendario.
610        // o celular não manda o nome do timezone apenas o offset dele dae não tem como saber qual foi o timezone selecionado.
611        $calendarSignatureTimezone = new DateTimeZone($calendar['timezone']) ;
612        $schedulable['startTime'] = (($message->starttime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->starttime + $GMT_CEL), new DateTimeZone('UTC'))) * -1) ) *1000; //$message->starttime  * 1000;
613        $schedulable['endTime'] = (($message->endtime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->endtime + $GMT_CEL), new DateTimeZone('UTC')))* -1)) *1000;//$message->endtime  * 1000;
614        $schedulable['timezone'] = $calendar['timezone'];
615
616
617        $sv  = new DateTime('@'.($message->starttime + $GMT_CEL), $calendarSignatureTimezone);
618
619        if($sv->format('I') == 0)
620            $schedulable['startTime'] = $schedulable['startTime'] - 3600000;
621
622        $ev  = new DateTime('@'.($message->endtime + $GMT_CEL), $calendarSignatureTimezone);
623
624        if($ev->format('I') == 0)
625            $schedulable['endTime'] = $schedulable['endTime'] - 3600000;
626
627        $schedulable['allDay'] = $message->alldayevent;
628        $schedulable['description'] = $message->body;
629        $schedulable['dtstamp'] = $message->dtstamp;
630        $schedulable['lastUpdate'] = time() * 1000;
631        $schedulable['type'] = '1';
632
633
634        if(isset($message->recurrence))
635        {
636            $repeatID = isset($schedulable['repeat']) ? $schedulable['repeat']['id'] : mt_rand() . '3(Formatter)';
637
638            $repeat = array();
639            $repeat['schedulable'] = $eventID;
640
641            switch( $message->recurrence->type )
642            {
643                case 0:
644                    $repeat['frequency'] = 'daily';
645                    break;
646                case 1:
647                    $repeat['frequency'] = 'weekly';
648                    break;
649                case 2:
650                    $repeat['frequency'] = 'monthly';
651                    break;
652                case 5:
653                    $repeat['frequency'] = 'yearly';
654                    break;
655            }
656
657            if(isset($message->recurrence->until))
658                $repeat['endTime'] =  $message->recurrence->until  * 1000 ;
659            else
660                $repeat['endTime'] = null;
661
662            $repeat['startTime'] =  $message->starttime * 1000 ;
663
664            $repeat['interval'] =  isset($message->recurrence->interval) ? $message->recurrence->interval : 1;
665
666            if(isset($message->recurrence->occurrences) && $message->recurrence->occurrences > 0)
667                $repeat["count"] = $message->recurrence->occurrences;
668            else
669                $repeat["count"] = 0;
670
671            if(isset($message->recurrence->weekofmonth) && $message->recurrence->weekofmonth > 0)
672                $repeat["byweekno"] =  $message->recurrence->weekofmonth;
673            else
674                $repeat["byweekno"] = 0;
675
676            if(isset($message->recurrence->dayofmonth) && $message->recurrence->dayofmonth > 0)
677                $repeat["bymonthday"] = $message->recurrence->dayofmonth;
678            else
679                $repeat["bymonthday"] = 0;
680
681            $day = $message->recurrence->dayofweek;
682            $day_of_week_array = array();
683            if (($day & 1) > 0) $day_of_week_array[] = 'SU';
684            if (($day & 2) > 0) $day_of_week_array[] = 'MO';
685            if (($day & 4) > 0) $day_of_week_array[] = 'TU';
686            if (($day & 8) > 0) $day_of_week_array[] = 'WE';
687            if (($day & 16) > 0) $day_of_week_array[] = 'TH';
688            if (($day & 32) > 0) $day_of_week_array[] = 'FR';
689            if (($day & 64) > 0) $day_of_week_array[] = 'SA';
690
691            $repeat["byday"] = implode(',' ,$day_of_week_array);
692            $interation['repeat://' . $repeatID] = $repeat;
693
694        }
695        else if (isset($schedulable['repeat']) )
696        {
697            $interation['repeat://'.$schedulable['repeat']['id']] = null;
698        }
699
700        $partForDelete = $schedulable['participants'];
701
702        foreach($partForDelete as $partForDeleteIndice => $partForDeleteValue)
703        {
704            if($partForDeleteValue['isOrganizer'] == '1')
705            {
706                if(isset($message->reminder) && $message->reminder > 0)
707                {
708                    $alarm = array();
709                    $alarmID =  isset($partForDeleteValue['alarms'][0]['id']) ? $partForDeleteValue['alarms'][0]['id'] :  mt_rand() . '6(Formatter)';
710                    $alarm['type'] = 'alert';
711                    $alarm['time'] = $message->reminder;
712                    $alarm['unit'] = 'm';
713
714                    foreach ($interation as $iint => &$vint)
715                    {
716                        if(isset($vint['user']) && $vint['user'] == $this->_uidnumber)
717                        {
718                            $alarm['participant'] = str_replace('participant://', '', $iint);
719                            $vint['alarms'][] = $alarmID;
720                        }
721                    }
722
723                    $alarm['schedulable'] = $eventID;
724                    $interation['alarm://' . $alarmID ] = $alarm;
725
726
727                }
728                else if(isset($partForDeleteValue['alarms'][0]['id']))
729                    $interation['alarm://' . $partForDeleteValue['alarms'][0]['id'] ] = false;
730
731                unset($partForDelete[$partForDeleteIndice]);
732                unset($schedulable['participants'][$partForDeleteIndice]['alarms']);
733            }
734        }
735
736        if(isset($message->attendees)  && count($message->attendees) > 0)
737        {
738
739            foreach($message->attendees as $attendee)
740            {
741
742                if($this->_getParticipantByMail($attendee->email, $schedulable['participants']) === false)
743                {
744                    $participantID = mt_rand() . '2(Formatter)';
745                    $participant = array();
746                    $participant['schedulable'] = $eventID;
747                    $participant['isOrganizer'] = '0';
748                    $participant['acl'] = 'r';
749
750                    /* Verifica se este usuario é um usuario interno do ldap */
751                    $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $attendee->email), array('=', 'mailAlternateAddress', $attendee->email))));
752
753                    $user = null;
754                    if ($intUser && count($intUser) > 0) {
755                        $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
756                        $participant['user'] = $intUser[0]['id'];
757                    } else {
758                        $participant['isExternal'] = 1;
759                        /* Gera um randon id para o contexto formater */
760                        $userID = mt_rand() . '4(Formatter)';
761
762                        $user['mail'] = $attendee->email;
763                        $user['name'] = ( isset($attendee->name) ) ? $attendee->name : '';
764                        $user['participants'] = array($participantID);
765                        $user['isExternal'] = '1';
766                        $participant['user'] = $userID;
767                        $interation['user://' . $userID] = $user;
768                    }
769
770                    $interation['participant://' . $participantID] = $participant;
771                    $schedulable['participants'][] = $participantID;
772                }
773                else
774                    unset($partForDelete[$this->_getParticipantByMail($attendee->email, $schedulable['participants'])]);
775
776            }
777
778        }
779
780        foreach( $partForDelete as $toDelete)
781        {
782            $interation['participant://' . $toDelete['id']] = false;
783            foreach ($schedulable['participants'] as $ipart => $part)
784            {
785                if($part['id'] == $toDelete['id'])
786                {
787                    unset($schedulable['participants'][$ipart]);
788                }
789            }
790
791            $schedulable['participants'] = array_merge($schedulable['participants'] , array());
792
793        }
794
795        foreach($schedulable['participants'] as $i => $v)
796        {
797            if($v['user']['id'] == $this->_uidnumber )
798            {
799                $schedulable['participants'][$i]['status'] = $this->formatBusy($message->busystatus);
800            }
801        }
802
803        unset($schedulable['repeat']);
804
805        $interation['schedulable://' . $eventID] = $schedulable;
806
807        ob_start();
808        $args = $interation;
809        include EXPRESSO_PATH.'/prototype/Sync.php';
810        ob_end_clean();
811
812        return $this->StatMessage($folderid, $message->uid);
813    }
814
815    private function createEvent($folderid, $idMessage, $message , $calendar)
816    {
817        $tz_CEL = $this->_getTZFromSyncBlob(base64_decode($message->timezone));
818        $GMT_CEL = -(($tz_CEL["bias"] + $tz_CEL["dstbias"]) * 60);
819
820
821        $interation = array();
822        $schedulable = array();
823        $eventID = mt_rand() . '(Formatter)';
824
825        $schedulable['calendar'] = $calendar['id'];
826        $schedulable['uid'] = $message->uid;
827        $schedulable['summary'] = $message->subject;
828        $schedulable['location'] = $message->location;
829        $schedulable['class'] = 1;
830
831
832        /// Eliminana o timezone, enviado pelo ceulular e coloca no timezone do calendario.
833        // o celular não manda o nome do timezone apenas o offset dele dae não tem como saber qual foi o timezone selecionado.
834        $calendarSignatureTimezone = new DateTimeZone($calendar['timezone']) ;
835        $schedulable['startTime'] = (($message->starttime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->starttime + $GMT_CEL), new DateTimeZone('UTC'))) * -1) ) *1000; //$message->starttime  * 1000;
836        $schedulable['endTime'] = (($message->endtime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->endtime + $GMT_CEL), new DateTimeZone('UTC')))* -1)) *1000;//$message->endtime  * 1000;
837
838        $sv  = new DateTime('@'.($message->starttime + $GMT_CEL), $calendarSignatureTimezone);
839
840        if($sv->format('I') == 0)
841            $schedulable['startTime'] = $schedulable['startTime'] - 3600000;
842
843        $ev  = new DateTime('@'.($message->endtime + $GMT_CEL), $calendarSignatureTimezone);
844
845        if($ev->format('I') == 0)
846            $schedulable['endTime'] = $schedulable['endTime'] - 3600000;
847
848        $schedulable['timezone'] = $calendar['timezone'];
849
850
851        $schedulable['allDay'] = $message->alldayevent;
852        $schedulable['description'] = $message->body;
853        $schedulable['dtstamp'] = $message->dtstamp;
854        // $schedulable['lastUpdate'] = 0;
855        $schedulable['type'] = '1';
856        $participant = array();
857        $participantID = mt_rand() . '2(Formatter)';
858        $participant['schedulable'] = $eventID;
859        $participant['isOrganizer'] = '1';
860        $participant['acl'] = 'rowi';
861        $participant['status'] = '1';
862
863        if($message->organizeremail)
864        {
865            /* Verifica se este usuario é um usuario interno do ldap */
866            $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $message->organizeremail), array('=', 'mailAlternateAddress', $message->organizeremail))));
867
868            $user = null;
869            if ($intUser && count($intUser) > 0) {
870                $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
871                $participant['user'] = $intUser[0]['id'];
872            } else {
873                $participant['isExternal'] = 1;
874                /* Gera um randon id para o contexto formater */
875                $userID = mt_rand() . '4(Formatter)';
876
877                $user['mail'] = $message->organizeremail;
878                $user['name'] = ( isset($message->organizername) ) ? $message->organizername : '';
879                $user['participants'] = array($participantID);
880                $user['isExternal'] = '1';
881                $participant['user'] = $userID;
882                $interation['user://' . $userID] = $user;
883            }
884        }
885        else
886        {
887            $participant['isExternal'] = 0;
888            $participant['user'] = $this->_uidnumber;
889            $participant['status'] = $this->formatBusy($message->busystatus);
890        }
891
892        //Caso exista recorrencias
893        if(isset($message->recurrence))
894        {
895            /* Gera um randon id para o contexto formater */
896            $repeatID = mt_rand() . '3(Formatter)';
897
898            $repeat = array();
899            $repeat['schedulable'] = $eventID;
900
901            switch( $message->recurrence->type )
902            {
903                case 0:
904                    $repeat['frequency'] = 'daily';
905                    break;
906                case 1:
907                    $repeat['frequency'] = 'weekly';
908                    break;
909                case 2:
910                    $repeat['frequency'] = 'monthly';
911                    break;
912                case 5:
913                    $repeat['frequency'] = 'yearly';
914                    break;
915            }
916
917            if(isset($message->recurrence->until))
918                $repeat['endTime'] =  $message->recurrence->until  * 1000 ;
919
920            $repeat['startTime'] =  $message->starttime * 1000 ;
921
922            $repeat['interval'] =  isset($message->recurrence->interval) ? $message->recurrence->interval : 1;
923
924            if(isset($message->recurrence->occurrences) && $message->recurrence->occurrences > 0)
925                $repeat["count"] = $message->recurrence->occurrences;
926
927            if(isset($message->recurrence->weekofmonth) && $message->recurrence->weekofmonth > 0)
928                $repeat["byweekno"] =  $message->recurrence->weekofmonth;
929
930            if(isset($message->recurrence->dayofmonth) && $message->recurrence->dayofmonth > 0)
931                $repeat["bymonthday"] = $message->recurrence->dayofmonth;
932
933            $day = $message->recurrence->dayofweek;
934            $day_of_week_array = array();
935            if (($day & 1) > 0) $day_of_week_array[] = 'SU';
936            if (($day & 2) > 0) $day_of_week_array[] = 'MO';
937            if (($day & 4) > 0) $day_of_week_array[] = 'TU';
938            if (($day & 8) > 0) $day_of_week_array[] = 'WE';
939            if (($day & 16) > 0) $day_of_week_array[] = 'TH';
940            if (($day & 32) > 0) $day_of_week_array[] = 'FR';
941            if (($day & 64) > 0) $day_of_week_array[] = 'SA';
942
943            $repeat["byday"] = implode(',' ,$day_of_week_array);
944            $interation['repeat://' . $repeatID] = $repeat;
945
946        }
947
948        $interation['participant://' . $participantID] = $participant;
949        $schedulable['participants'][] = $participantID;
950
951
952        if(isset($message->attendees)  && count($message->attendees) > 0)
953        {
954            foreach($message->attendees as $attendee)
955            {
956                $participantID = mt_rand() . '2(Formatter)';
957                $participant = array();
958                $participant['schedulable'] = $eventID;
959                $participant['isOrganizer'] = '0';
960                $participant['acl'] = 'r';
961
962                /* Verifica se este usuario é um usuario interno do ldap */
963                $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $attendee->email), array('=', 'mailAlternateAddress', $attendee->email))));
964
965                $user = null;
966                if ($intUser && count($intUser) > 0) {
967                    $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
968                    $participant['user'] = $intUser[0]['id'];
969                } else {
970                    $participant['isExternal'] = 1;
971                    /* Gera um randon id para o contexto formater */
972                    $userID = mt_rand() . '4(Formatter)';
973
974                    $user['mail'] = $attendee->email;
975                    $user['name'] = ( isset($attendee->name) ) ? $attendee->name : '';
976                    $user['participants'] = array($participantID);
977                    $user['isExternal'] = '1';
978                    $participant['user'] = $userID;
979                    $interation['user://' . $userID] = $user;
980
981                    if($userID == $this->_uidnumber)
982                    {
983                        $participant['status'] = $this->formatBusy($message->busystatus);
984                    }
985
986                }
987
988                $interation['participant://' . $participantID] = $participant;
989                $schedulable['participants'][] = $participantID;
990
991            }
992
993        }
994
995        if(isset($message->reminder) && $message->reminder > 0)
996        {
997            $alarm = array();
998            $alarmID = mt_rand() . '6(Formatter)';
999            $alarm['type'] = 'alert';
1000            $alarm['time'] = $message->reminder;
1001            $alarm['unit'] = 'm';
1002
1003            foreach ($interation as $iint => &$vint)
1004            {
1005                if(isset($vint['user']) && $vint['user'] == $this->_uidnumber)
1006                {
1007                    $alarm['participant'] = str_replace('participant://', '', $iint);
1008                    $vint['alarms'][] = $alarmID;
1009                }
1010            }
1011
1012            $alarm['schedulable'] = $eventID;
1013            $interation['alarm://' . $alarmID ] = $alarm;
1014
1015
1016        }
1017
1018        $interation['schedulable://' . $eventID] = $schedulable;
1019
1020        ob_start();
1021        $args = $interation;
1022        include EXPRESSO_PATH.'/prototype/Sync.php';
1023        ob_end_clean();
1024
1025        return $this->StatMessage($folderid, $message->uid);
1026    }
1027
1028
1029    /**
1030     * Changes the 'read' flag of a message on disk. The $flags
1031     * parameter can only be '1' (read) or '0' (unread). After a call to
1032     * SetReadFlag(), GetMessageList() should return the message with the
1033     * new 'flags' but should not modify the 'mod' parameter. If you do
1034     * change 'mod', simply setting the message to 'read' on the mobile will trigger
1035     * a full resync of the item from the server.
1036     *
1037     * @param string        $folderid       id of the folder
1038     * @param string        $id             id of the message
1039     * @param int           $flags          read flag of the message
1040     *
1041     * @access public
1042     * @return boolean                      status of the operation
1043     * @throws StatusException              could throw specific SYNC_STATUS_* exceptions
1044     */
1045    public function SetReadFlag($folderid, $id, $flags)
1046    {
1047        return true;
1048    }
1049
1050    /**
1051     * Called when the user has requested to delete (really delete) a message. Usually
1052     * this means just unlinking the file its in or somesuch. After this call has succeeded, a call to
1053     * GetMessageList() should no longer list the message. If it does, the message will be re-sent to the mobile
1054     * as it will be seen as a 'new' item. This means that if this method is not implemented, it's possible to
1055     * delete messages on the PDA, but as soon as a sync is done, the item will be resynched to the mobile
1056     *
1057     * @param string        $folderid       id of the folder
1058     * @param string        $id             id of the message
1059     *
1060     * @access public
1061     * @return boolean                      status of the operation
1062     * @throws StatusException              could throw specific SYNC_STATUS_* exceptions
1063     */
1064    public function DeleteMessage($folderid, $id)
1065    {
1066
1067        $idNumber = (int)str_replace('calendar' , '' , $folderid);
1068        $calendarSignature =  Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
1069        $even = $this->_getSchedulable($id );
1070        $calendar =  Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
1071
1072        $link = Controller::read(array('concept' => 'calendarToSchedulable'), false, array('filter' => array('AND', array('=','calendar',$calendarSignature['calendar']), array('=','schedulable',$even['id']))));
1073
1074        $delete = false;
1075        foreach($even['participants'] as $i => $v)
1076        {
1077            if($v['user']['id'] == $this->_uidnumber && $v['user']['isOrganizer']  == '1')
1078            {
1079                $delete = true;
1080            }
1081        }
1082
1083        if( $delete === true)
1084        {
1085            Controller::delete(array('concept' => 'schedulable' , 'id' => $even['id']));
1086        }
1087        else
1088        {
1089            Controller::delete(array('concept' => 'calendarToSchedulable', 'id' => $link[0]['id']));
1090
1091            foreach($even['participants'] as $i => $v)
1092            {
1093                if($v['user']['id'] == $this->_uidnumber)
1094                {
1095                    Controller::update(array('concept' => 'participant','id' => $v['id']), array('status' => STATUS_CANCELLED ));
1096                }
1097            }
1098
1099        }
1100        return true;
1101    }
1102
1103    /**
1104     * Called when the user moves an item on the PDA from one folder to another. Whatever is needed
1105     * to move the message on disk has to be done here. After this call, StatMessage() and GetMessageList()
1106     * should show the items to have a new parent. This means that it will disappear from GetMessageList()
1107     * of the sourcefolder and the destination folder will show the new message
1108     *
1109     * @param string        $folderid       id of the source folder
1110     * @param string        $id             id of the message
1111     * @param string        $newfolderid    id of the destination folder
1112     *
1113     * @access public
1114     * @return boolean                      status of the operation
1115     * @throws StatusException              could throw specific SYNC_MOVEITEMSSTATUS_* exceptions
1116     */
1117    public function MoveMessage($folderid, $id, $newfolderid)
1118    {
1119        return false;
1120    }
1121
1122    /**
1123     * Authenticates the user
1124     *
1125     * @param string        $username
1126     * @param string        $domain
1127     * @param string        $password
1128     *
1129     * @access public
1130     * @return boolean
1131     * @throws FatalException   e.g. some required libraries are unavailable
1132     */
1133    public function Logon($username, $domain, $password)
1134    {
1135        $ldapConfig = parse_ini_file(EXPRESSO_PATH . '/prototype/config/OpenLDAP.srv' , true );
1136        $ldapConfig =  $ldapConfig['config'];
1137
1138        $sr = ldap_search( $GLOBALS['connections']['ldap'] , $ldapConfig['context'] , "(uid=$username)" , array('uidNumber','uid','mail'), 0 , 1 );
1139        if(!$sr) return false;
1140
1141        $entries = ldap_get_entries( $GLOBALS['connections']['ldap'] , $sr );
1142        $this->_uidnumber = $entries[0]['uidnumber'][0];
1143
1144
1145        //Inicia Variaveis de para API expresso
1146        if(!isset($_SESSION))
1147            session_start();
1148
1149        $userWallet = array();
1150        $userWallet['uidNumber'] = $entries[0]['uidnumber'][0];
1151        $userWallet['uid'] = $entries[0]['uid'][0];
1152        $userWallet['mail'] = $entries[0]['mail'][0];
1153
1154        $_SESSION['wallet'] = array();
1155        $_SESSION['wallet']['user'] = $userWallet;
1156        $_SESSION['flags']['currentapp'] = 'expressoCalendar';
1157
1158        //----------------------------------------------------------------------------------------//
1159
1160        return true;
1161    }
1162
1163    /**
1164     * Logs off
1165     * non critical operations closing the session should be done here
1166     *
1167     * @access public
1168     * @return boolean
1169     */
1170    public function Logoff()
1171    {
1172
1173    }
1174
1175    /**
1176     * Sends an e-mail
1177     * This messages needs to be saved into the 'sent items' folder
1178     *
1179     * Basically two things can be done
1180     *      1) Send the message to an SMTP server as-is
1181     *      2) Parse the message, and send it some other way
1182     *
1183     * @param SyncSendMail        $sm         SyncSendMail object
1184     *
1185     * @access public
1186     * @return boolean
1187     * @throws StatusException
1188     */
1189    public function SendMail($sm)
1190    {
1191        return false;
1192    }
1193
1194    /**
1195     * Returns the waste basket
1196     *
1197     * The waste basked is used when deleting items; if this function returns a valid folder ID,
1198     * then all deletes are handled as moves and are sent to the backend as a move.
1199     * If it returns FALSE, then deletes are handled as real deletes
1200     *
1201     * @access public
1202     * @return string
1203     */
1204    public function GetWasteBasket()
1205    {
1206        return false;
1207    }
1208
1209    /**
1210     * Returns the content of the named attachment as stream. The passed attachment identifier is
1211     * the exact string that is returned in the 'AttName' property of an SyncAttachment.
1212     * Any information necessary to locate the attachment must be encoded in that 'attname' property.
1213     * Data is written directly - 'print $data;'
1214     *
1215     * @param string        $attname
1216     *
1217     * @access public
1218     * @return SyncItemOperationsAttachment
1219     * @throws StatusException
1220     */
1221    public function GetAttachmentData($attname)
1222    {
1223        return false;
1224    }
1225
1226    function _getGMTTZ() {
1227        //$tz = array("bias" => 0, "stdbias" => 0, "dstbias" => 0, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0,
1228        //"dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0);
1229        $tz = array("bias" => 120, "stdbias" => 0, "dstbias" => -60, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0, "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0);
1230
1231        return $tz;
1232    }
1233    function _getSyncBlobFromTZ($tz) {
1234        $packed = pack("la64vvvvvvvv" . "la64vvvvvvvv" . "l",
1235            $tz["bias"], "", 0, $tz["dstendmonth"], $tz["dstendday"], $tz["dstendweek"], $tz["dstendhour"], $tz["dstendminute"], $tz["dstendsecond"], $tz["dstendmillis"],
1236            $tz["stdbias"], "", 0, $tz["dststartmonth"], $tz["dststartday"], $tz["dststartweek"], $tz["dststarthour"], $tz["dststartminute"], $tz["dststartsecond"], $tz["dststartmillis"],
1237            $tz["dstbias"]);
1238
1239        return $packed;
1240    }
1241
1242    function _getTZFromSyncBlob($data) {
1243        $tz = unpack(    "lbias/a64name/vdstendyear/vdstendmonth/vdstendday/vdstendweek/vdstendhour/vdstendminute/vdstendsecond/vdstendmillis/" .
1244            "lstdbias/a64name/vdststartyear/vdststartmonth/vdststartday/vdststartweek/vdststarthour/vdststartminute/vdststartsecond/vdststartmillis/" .
1245            "ldstbias", $data);
1246
1247        // Make the structure compatible with class.recurrence.php
1248        $tz["timezone"] = $tz["bias"];
1249        $tz["timezonedst"] = $tz["dstbias"];
1250
1251        return $tz;
1252    }
1253
1254    private function formatDoWeek($week)
1255    {
1256        $recday = explode(',' , $week);
1257        $nday = 0;
1258        foreach ($recday as $day)
1259        {
1260            switch($day)
1261            {
1262                case 'SU':
1263                    $nday=$nday +1;
1264                    break;
1265                case 'MO':
1266                    $nday=$nday +2;
1267                    break;
1268                case 'TU':
1269                    $nday=$nday +4;
1270                    break;
1271                case 'WE':
1272                    $nday=$nday +8;
1273                    break;
1274                case 'TH':
1275                    $nday=$nday +16;
1276                    break;
1277                case 'FR':
1278                    $nday=$nday +32;
1279                    break;
1280                case 'SA':
1281                    $nday=$nday +64;
1282                    break;
1283
1284            }
1285        }
1286        return $nday;
1287    }
1288
1289    private function _getParticipantByMail($mail, &$participants, $isFull = false) {
1290        if ($participants && $participants != '')
1291            foreach ($participants as $i => $v)
1292                if ((is_array($v) && isset($v['user'])) && ($v['user']['mail'] == $mail || (isset($v['user']['mailAlternateAddress']) && in_array($mail, $v['user']['mailAlternateAddress']))))
1293                    return $i;
1294        return false;
1295    }
1296
1297    private function _getParticipantIDByMail($mail, &$participants, $isFull = false) {
1298        if ($participants && $participants != '')
1299            foreach ($participants as $i => $v)
1300                if ((is_array($v) && isset($v['user'])) && ($v['user']['mail'] == $mail || (isset($v['user']['mailAlternateAddress']) && in_array($mail, $v['user']['mailAlternateAddress']))))
1301                    return !!$isFull ? $v : $v['id'];
1302        return false;
1303    }
1304
1305
1306    private function formatBusy($status)
1307    {
1308        switch($status)
1309        {
1310            case 2:
1311                return STATUS_ACCEPTED;
1312                break;
1313            case 1:
1314                return STATUS_TENTATIVE;
1315                break;
1316            case 3:
1317                return STATUS_DECLINED;
1318                break;
1319            case 0:
1320                return STATUS_UNANSWERED;
1321                break;
1322        }
1323    }
1324
1325
1326
1327}
Note: See TracBrowser for help on using the repository browser.