PageRenderTime 4ms CodeModel.GetById 40ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 1ms

/zpush/backend/expresso/providers/calendarProvider.php

https://github.com/muchael/expressolivre
PHP | 1327 lines | 866 code | 218 blank | 243 comment | 153 complexity | 52481b5e537df2669e17e1358059fc7c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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 = 1440;
 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, $contentParameters)
 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, $contentParameters)
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, $contentParameters)
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 , $contentParameters)
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         Sy…

Large files files are truncated, but you can click here to view the full file