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

Revision 7687, 49.5 KB checked in by cristiano, 11 years ago (diff)

Ticket #3209 - ErSincronização? de status e acl de edição

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