PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms 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
Possible License(s): GPL-2.0, LGPL-2.1, BSD-2-Clause, BSD-3-Clause, AGPL-3.0

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

  1. <?php
  2. require_once __DIR__ . '/../../../lib/default/diffbackend/diffbackend.php';
  3. require_once EXPRESSO_PATH . '/prototype/api/controller.php';
  4. require_once EXPRESSO_PATH . '/prototype/api/config.php';
  5. require_once EXPRESSO_PATH . '/prototype/modules/calendar/constants.php';
  6. use prototype\api\Config as Config;
  7. class ExpressoCalendarProvider extends BackendDiff
  8. {
  9. var $_uidnumber;
  10. function __construct()
  11. {
  12. }
  13. /**
  14. * Returns a list (array) of folders, each entry being an associative array
  15. * with the same entries as StatFolder(). This method should return stable information; ie
  16. * if nothing has changed, the items in the array must be exactly the same. The order of
  17. * the items within the array is not important though.
  18. *
  19. * @access protected
  20. * @return array/boolean false if the list could not be retrieved
  21. */
  22. public function GetFolderList()
  23. {
  24. $return = array();
  25. $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 )));
  26. $sigs = Controller::find(array('concept' => 'calendarSignature'), array( 'id','calendar' ), $criteria);
  27. if(Request::GetDeviceType() == 'iPhone' || Request::GetDeviceType() == 'iPad')
  28. {
  29. foreach($sigs as $sig)
  30. {
  31. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
  32. $tmpSig = array();
  33. $tmpSig["id"] = 'calendar'.$sig['id'];
  34. $tmpSig["parent"] = 0;
  35. $tmpSig["mod"] = $calendar['name'];
  36. $return[] = $tmpSig;
  37. }
  38. }
  39. else
  40. {
  41. $defaultCalendar = Controller::find(array('concept' => 'modulePreference'), array('value','id') , array('filter' => array( 'and' , array('=' , 'name' , 'defaultCalendar') , array('=' , 'module' , 'expressoCalendar') , array('=' , 'user' , $this->_uidnumber ) )) );
  42. if(isset($defaultCalendar[0])) //Prioriza agenda default de importação pois o android so sincroniza a primeira agenda.
  43. {
  44. foreach($sigs as $i => $sig)
  45. {
  46. if($sig['calendar'] == $defaultCalendar[0]['value'])
  47. {
  48. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
  49. $tmpSig = array();
  50. $tmpSig["id"] = 'calendar'.$sig['id'];
  51. $tmpSig["parent"] = 0;
  52. $tmpSig["mod"] = $calendar['name'];
  53. $return[] = $tmpSig;
  54. }
  55. }
  56. }
  57. else
  58. {
  59. $sig = $sigs[0];
  60. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $sig['calendar'] ));
  61. $tmpSig = array();
  62. $tmpSig["id"] = 'calendar'.$sig['id'];
  63. $tmpSig["parent"] = 0;
  64. $tmpSig["mod"] = $calendar['name'];
  65. $return[] = $tmpSig;
  66. }
  67. }
  68. return $return;
  69. }
  70. /**
  71. * Returns an actual SyncFolder object with all the properties set. Folders
  72. * are pretty simple, having only a type, a name, a parent and a server ID.
  73. *
  74. * @param string $id id of the folder
  75. *
  76. * @access public
  77. * @return object SyncFolder with information
  78. */
  79. public function GetFolder($id)
  80. {
  81. $idNumber = (int)str_replace('calendar' , '' , $id);
  82. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  83. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
  84. if(is_array($calendarSignature) && count($calendarSignature) > 0 )
  85. {
  86. $folder = new SyncFolder();
  87. $folder->serverid = $id;
  88. $folder->parentid = "0";
  89. $folder->displayname = $calendar['name'];
  90. $folder->type = SYNC_FOLDER_TYPE_APPOINTMENT;
  91. return $folder;
  92. }
  93. return false;
  94. }
  95. /**
  96. * Returns folder stats. An associative array with properties is expected.
  97. *
  98. * @param string $id id of the folder
  99. *
  100. * @access public
  101. * @return array
  102. * Associative array(
  103. * string "id" The server ID that will be used to identify the folder. It must be unique, and not too long
  104. * How long exactly is not known, but try keeping it under 20 chars or so. It must be a string.
  105. * string "parent" The server ID of the parent of the folder. Same restrictions as 'id' apply.
  106. * long "mod" This is the modification signature. It is any arbitrary string which is constant as long as
  107. * the folder has not changed. In practice this means that 'mod' can be equal to the folder name
  108. * as this is the only thing that ever changes in folders. (the type is normally constant)
  109. * )
  110. */
  111. public function StatFolder($id)
  112. {
  113. $return = array();
  114. $idNumber = (int)str_replace('calendar' , '' , $id);
  115. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  116. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
  117. $return["id"] = $id;
  118. $return["parent"] = 0;
  119. $return["mod"] = $calendar['name'];
  120. return $return;
  121. }
  122. /**
  123. * Creates or modifies a folder
  124. *
  125. * @param string $folderid id of the parent folder
  126. * @param string $oldid if empty -> new folder created, else folder is to be renamed
  127. * @param string $displayname new folder name (to be created, or to be renamed to)
  128. * @param int $type folder type
  129. *
  130. * @access public
  131. * @return boolean status
  132. * @throws StatusException could throw specific SYNC_FSSTATUS_* exceptions
  133. *
  134. */
  135. public function ChangeFolder($folderid, $oldid, $displayname, $type)
  136. {
  137. if($oldid)
  138. {
  139. $idNumber = (int)str_replace('calendar' , '' , $oldid);
  140. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  141. Controller::update( array('concept' => 'calendar' , 'id' => $calendarSignature['calendar']), array( 'name' => $displayname) );
  142. return $this->StatFolder($oldid);
  143. }
  144. else
  145. {
  146. $cal = array('name' => $displayname,
  147. 'timezone' => 'America/Sao_Paulo',
  148. 'type' => '0'
  149. );
  150. $calCreated = Controller::create(array('concept' => 'calendar'), $cal);
  151. if(!$calCreated){
  152. return false;
  153. }
  154. $sig = array('user' => $_SESSION['wallet']['user']['uidNumber'],
  155. 'calendar' => $calCreated['id'],
  156. 'isOwner' => '1',
  157. 'dtstamp' => time() . '000',
  158. 'fontColor' => 'FFFFFF',
  159. 'backgroundColor' => '3366CC',
  160. 'borderColor' => '3366CC',
  161. );
  162. $sigCreated = Controller::create(array('concept' => 'calendarSignature'), $sig);
  163. if(!$sigCreated){
  164. return false;
  165. }
  166. else
  167. {
  168. $return = array();
  169. $return["id"] = 'calendar'.$calCreated;
  170. $return["parent"] = 0;
  171. $return["mod"] = $displayname;
  172. return $return;
  173. }
  174. }
  175. return false;
  176. }
  177. /**
  178. * Deletes a folder
  179. *
  180. * @param string $id
  181. * @param string $parent is normally false
  182. *
  183. * @access public
  184. * @return boolean status - false if e.g. does not exist
  185. * @throws StatusException could throw specific SYNC_FSSTATUS_* exceptions
  186. */
  187. public function DeleteFolder($id, $parent)
  188. {
  189. $interation = array();
  190. $idNumber = (int)str_replace('calendar' , '' , $id);
  191. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  192. $interation['calendar://' . $calendarSignature['calendar']] = false;
  193. ob_start();
  194. $args = $interation;
  195. include EXPRESSO_PATH.'/prototype/Sync.php';
  196. ob_end_clean();
  197. return true;
  198. }
  199. /**
  200. * Returns a list (array) of messages, each entry being an associative array
  201. * with the same entries as StatMessage(). This method should return stable information; ie
  202. * if nothing has changed, the items in the array must be exactly the same. The order of
  203. * the items within the array is not important though.
  204. *
  205. * The $cutoffdate is a date in the past, representing the date since which items should be shown.
  206. * This cutoffdate is determined by the user's setting of getting 'Last 3 days' of e-mail, etc. If
  207. * the cutoffdate is ignored, the user will not be able to select their own cutoffdate, but all
  208. * will work OK apart from that.
  209. *
  210. * @param string $folderid id of the parent folder
  211. * @param long $cutoffdate timestamp in the past from which on messages should be returned
  212. *
  213. * @access public
  214. * @return array/false array with messages or false if folder is not available
  215. */
  216. public function GetMessageList($folderid, $cutoffdate)
  217. {
  218. $idNumber = (int)str_replace('calendar' , '' , $folderid);
  219. $cal_ids = null;
  220. $messages = array();
  221. $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';
  222. $rs = Controller::service('PostgreSQL')->execSql($sql);
  223. if(is_array($rs))
  224. {
  225. foreach($rs as $v)
  226. {
  227. $message = array();
  228. $message["id"] = $v['cal_uid'];
  229. $message["mod"] = substr($v['last_update'], 0, -3);
  230. $message["flags"] = 1; // always 'read'
  231. $messages[] = $message;
  232. }
  233. }
  234. return $messages;
  235. }
  236. /**
  237. * Returns the actual SyncXXX object type. The '$folderid' of parent folder can be used.
  238. * Mixing item types returned is illegal and will be blocked by the engine; ie returning an Email object in a
  239. * Tasks folder will not do anything. The SyncXXX objects should be filled with as much information as possible,
  240. * but at least the subject, body, to, from, etc.
  241. *
  242. * @param string $folderid id of the parent folder
  243. * @param string $id id of the message
  244. * @param ContentParameters $contentparameters parameters of the requested message (truncation, mimesupport etc)
  245. *
  246. * @access public
  247. * @return object/false false if the message could not be retrieved
  248. */
  249. public function GetMessage($folderid, $id, $contentparameters)
  250. {
  251. $idNumber = (int)str_replace('calendar' , '' , $folderid);
  252. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  253. $schedulable = Controller::find(array('concept' => 'schedulable'), null , array('filter' => array( '=' , 'uid' , $id)));
  254. if( is_array($schedulable) && count($schedulable) > 0 )
  255. $schedulable = $schedulable[0];
  256. else
  257. return false;
  258. $message = new SyncAppointment();
  259. $message->uid = $id;
  260. $message->dtstamp = (int) substr($schedulable['dtstamp'], 0, -3);
  261. $message->starttime = (int) substr($schedulable['startTime'], 0, -3);
  262. $message->endtime = (int) substr($schedulable['endTime'], 0, -3);
  263. $message->deleted = 0;
  264. $message->subject = mb_convert_encoding($schedulable['summary'] , 'UTF-8' , 'UTF-8,ISO-8859-1');
  265. $message->location = mb_convert_encoding($schedulable['location'], 'UTF-8' , 'UTF-8,ISO-8859-1');
  266. if(isset($schedulable['description']) && $schedulable['description'] != "") {
  267. $message->body = mb_convert_encoding($schedulable['description'], 'UTF-8' , 'UTF-8,ISO-8859-1'); // phpgw_cal.description
  268. $message->bodysize = strlen($message->body);
  269. $message->bodytruncated = 0;
  270. }
  271. $message->sensitivity = 0; // 0 - Normal,
  272. $message->alldayevent = (int)$schedulable['allDay']; // (0 - Não(default), 1- Sim)
  273. $message->timezone = base64_encode($this->_getSyncBlobFromTZ($this->_getGMTTZ()));
  274. /*
  275. * Sincronização de participantes e organizador
  276. */
  277. $participants = Controller::find(array('concept' => 'participant'), null , array('deepness' => 1 , 'filter' => array( '=' , 'schedulable' , $schedulable['id'] )));
  278. if(is_array($participants) && count($participants) > 0)
  279. {
  280. $message->attendees = array();
  281. foreach($participants as $participant)
  282. {
  283. if($participant['isOrganizer'] == 1) //organizador
  284. {
  285. $message->organizername = mb_convert_encoding($participant['user']['name'], 'UTF-8' , 'UTF-8,ISO-8859-1');
  286. $message->organizeremail = mb_convert_encoding($participant['user']['mail'], 'UTF-8' , 'UTF-8,ISO-8859-1');
  287. }
  288. else
  289. {
  290. $attendee = new SyncAttendee();
  291. $attendee->name = mb_convert_encoding($participant['user']['name'], 'UTF-8' , 'UTF-8,ISO-8859-1');
  292. $attendee->email = mb_convert_encoding($participant['user']['mail'], 'UTF-8' , 'UTF-8,ISO-8859-1');
  293. $message->attendees[] = $attendee;
  294. }
  295. if($participant['user']['id'] == $this->_uidnumber )
  296. {
  297. if($participant['isOrganizer'] == 1 || strpos($participant['acl'] ,'w') !== false) // Caso ele seja organizador ou tenha permisão de editar o evento
  298. {
  299. $message->meetingstatus = 0;
  300. }
  301. else
  302. {
  303. $message->meetingstatus = 3;
  304. }
  305. if(isset($participant['alarms'][0]) )
  306. {
  307. switch($participant['alarms'][0]['unit'])
  308. {
  309. case 'h':
  310. $mult = 60;
  311. break;
  312. case 'd':
  313. $mult = 1440;
  314. break;
  315. default:
  316. $mult = 1;
  317. break;
  318. }
  319. $message->reminder = $participant['alarms'][0]['time'] * $mult;
  320. }
  321. switch($participant['status'])
  322. {
  323. case STATUS_ACCEPTED:
  324. $message->busystatus = 2;
  325. break;
  326. case STATUS_TENTATIVE:
  327. $message->busystatus = 1;
  328. break;
  329. case STATUS_DECLINED:
  330. $message->busystatus = 3;
  331. break;
  332. case STATUS_UNANSWERED:
  333. $message->busystatus = 0;
  334. break;
  335. }
  336. }
  337. }
  338. }
  339. //------------------------------------------------------------------------------------------------------------//
  340. /*
  341. * Sincronização de Recorrência
  342. */
  343. $repeats = Controller::find(array('concept' => 'repeat'), null , array( 'filter' => array( 'and' , array( '=' , 'schedulable' , $schedulable['id'] ),array( '!=' , 'frequency' , 'none' ) ) ));
  344. if(is_array($repeats) && count($repeats) > 0)
  345. {
  346. $repeat = $repeats[0];
  347. $recur = new SyncRecurrence();
  348. switch($repeat['frequency'])
  349. {
  350. case 'daily':
  351. $recur->type = 0;
  352. break;
  353. case 'weekly':
  354. $recur->type = 1;
  355. break;
  356. case 'monthly':
  357. $recur->type = 2;
  358. break;
  359. case 'yearly':
  360. $recur->type = 5;
  361. break;
  362. }
  363. if($repeat['endTime'])
  364. $recur->until = (int) substr($repeat['endTime'], 0, -3);
  365. $recur->interval = $repeat['interval'] ? $repeat['interval'] : 1;
  366. if($repeat["count"])
  367. $recur->occurrences = (int)$repeat["count"];
  368. if($repeat["byweekno"])
  369. $recur->weekofmonth = (int)$repeat["byweekno"];
  370. if($repeat["bymonthday"])
  371. $recur->dayofmonth = (int)$repeat["bymonthday"];
  372. if($repeat["byday"])
  373. $recur->dayofweek = $this->formatDoWeek($repeat["byday"]);
  374. //$recurrence->monthofyear ; //Não implementado no expresso
  375. $expetions = Controller::find(array('concept' => 'repeatOccurrence'), null , array( 'filter' => array( 'and' , array( '=' , 'exception' , '1' ),array( '=' , 'repeat' , $repeat['id'] ) )));
  376. if(is_array($expetions) && count($expetions) > 0)
  377. {
  378. $message->exceptions = array();
  379. foreach($expetions as $expetion)
  380. {
  381. $exception = new SyncAppointmentException();
  382. $exception->exceptionstarttime = (int) substr($expetion['occurrence'], 0, -3);
  383. $exception->deleted = '1';
  384. $message->exceptions[] = $exception;
  385. }
  386. }
  387. $message->recurrence = $recur;
  388. }
  389. return $message;
  390. }
  391. /**
  392. * Returns message stats, analogous to the folder stats from StatFolder().
  393. *
  394. * @param string $folderid id of the folder
  395. * @param string $id id of the message
  396. *
  397. * @access public
  398. * @return array or boolean if fails
  399. * Associative array(
  400. * string "id" Server unique identifier for the message. Again, try to keep this short (under 20 chars)
  401. * int "flags" simply '0' for unread, '1' for read
  402. * long "mod" This is the modification signature. It is any arbitrary string which is constant as long as
  403. * the message has not changed. As soon as this signature changes, the item is assumed to be completely
  404. * changed, and will be sent to the PDA as a whole. Normally you can use something like the modification
  405. * time for this field, which will change as soon as the contents have changed.
  406. * )
  407. */
  408. public function StatMessage($folderid, $id)
  409. {
  410. $sql = 'SELECT last_update , cal_uid FROM calendar_object WHERE cal_uid = \''.pg_escape_string($id) .'\'';
  411. $message = array();
  412. $rs = Controller::service('PostgreSQL')->execSql($sql);
  413. if(is_array($rs))
  414. {
  415. $message["mod"] = substr($rs[0]['last_update'], 0, -3);
  416. $message["id"] = $id;
  417. $message["flags"] = 1;
  418. }
  419. return $message;
  420. }
  421. /**
  422. * Called when a message has been changed on the mobile. The new message must be saved to disk.
  423. * The return value must be whatever would be returned from StatMessage() after the message has been saved.
  424. * This way, the 'flags' and the 'mod' properties of the StatMessage() item may change via ChangeMessage().
  425. * This method will never be called on E-mail items as it's not 'possible' to change e-mail items. It's only
  426. * possible to set them as 'read' or 'unread'.
  427. *
  428. * @param string $folderid id of the folder
  429. * @param string $id id of the message
  430. * @param SyncXXX $message the SyncObject containing a message
  431. *
  432. * @access public
  433. * @return array same return value as StatMessage()
  434. * @throws StatusException could throw specific SYNC_STATUS_* exceptions
  435. */
  436. public function ChangeMessage($folderid, $idMessage, $message, $contentParameters)
  437. {
  438. $idNumber = (int)str_replace('calendar' , '' , $folderid);
  439. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  440. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
  441. if($idMessage)
  442. {
  443. $schedulable = Controller::find(array('concept' => 'schedulable'), null , array('deepness'=> 2 , 'filter' => array( '=' , 'uid' , $idMessage)));
  444. $schedulable = $schedulable[0];
  445. foreach($schedulable['participants'] as $i => $v)
  446. {
  447. if($v['user']['id'] == $this->_uidnumber )
  448. {
  449. if(strpos($v['acl'] ,'w') !== false) //Caso o usuario tenha permissão de editar o evento
  450. {
  451. return $this->updateEvent($folderid, $idMessage, $message , $calendar ,$schedulable);
  452. }
  453. else
  454. {
  455. $interation = array();
  456. if(isset($message->reminder) && $message->reminder > 0)
  457. {
  458. $alarm = array();
  459. $alarmID = mt_rand() . '6(Formatter)';
  460. $alarm['type'] = 'alert';
  461. $alarm['time'] = $message->reminder;
  462. $alarm['unit'] = 'm';
  463. $alarm['participant'] = $v['id'];
  464. $alarm['schedulable'] = $schedulable['id'];
  465. $interation['alarm://' . $alarmID ] = $alarm;
  466. }
  467. $status = $this->formatBusy($message->busystatus);
  468. if($status == STATUS_DECLINED ) //Caso ele não seja dono do evento e recusou o convite deletar o evento da sua agenda.
  469. {
  470. Controller::deleteAll(array('concept' => 'calendarToSchedulable' ) , false , array('filter' => array('AND', array('=','calendar',$calendarSignature['calendar']), array('=','schedulable',$schedulable['id']))));
  471. }
  472. $v['status'] = $status;
  473. $interation['participant://' . $v['id'] ] = $v;
  474. ob_start();
  475. $args = $interation;
  476. include EXPRESSO_PATH.'/prototype/Sync.php';
  477. ob_end_clean();
  478. }
  479. }
  480. }
  481. return $this->StatMessage($folderid, $message->uid);
  482. }
  483. else
  484. {
  485. if (!$schedulable = $this->_getSchedulable($message->uid))
  486. return $this->createEvent($folderid, $idMessage, $message ,$calendar);
  487. else{
  488. $links = Controller::read(array('concept' => 'calendarToSchedulable'), array('id'), array('filter' =>
  489. array('AND',
  490. array('=', 'calendar', $calendar['id']),
  491. array('=', 'schedulable', $schedulable['id'])
  492. )));
  493. if(!$links && !isset($links[0]))
  494. Controller::create(array('concept' => 'calendarToSchedulable'), array('calendar' => $calendar['id'], 'schedulable' => $schedulable['id']));
  495. foreach($schedulable['participants'] as $i => $v)
  496. {
  497. if($v['user']['id'] == $this->_uidnumber)
  498. {
  499. Controller::update(array('concept' => 'participant','id' => $v['id']), array('status' => $this->formatBusy($message->busystatus ) ));
  500. }
  501. }
  502. return $this->StatMessage($folderid, $message->uid);
  503. }
  504. }
  505. }
  506. private function _getSchedulable($uid) {
  507. $schedulable = Controller::find(array('concept' => 'schedulable'), false, array('filter' => array('=', 'uid', $uid), 'deepness' => 2));
  508. return (isset($schedulable[0])) ? $schedulable[0] : false;
  509. }
  510. private function updateEvent($folderid, $idMessage, $message , $calendar ,$schedulable )
  511. {
  512. $tz_CEL = $this->_getTZFromSyncBlob(base64_decode($message->timezone));
  513. $GMT_CEL = -(($tz_CEL["bias"] + $tz_CEL["dstbias"]) * 60);
  514. $interation = array();
  515. $eventID = $schedulable['id'];
  516. $schedulable['uid'] = $message->uid;
  517. $schedulable['summary'] = $message->subject;
  518. $schedulable['location'] = $message->location;
  519. $schedulable['class'] = 1;
  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. $sv = new DateTime('@'.($message->starttime + $GMT_CEL), $calendarSignatureTimezone);
  527. if($sv->format('I') == 0)
  528. $schedulable['startTime'] = $schedulable['startTime'] - 3600000;
  529. $ev = new DateTime('@'.($message->endtime + $GMT_CEL), $calendarSignatureTimezone);
  530. if($ev->format('I') == 0)
  531. $schedulable['endTime'] = $schedulable['endTime'] - 3600000;
  532. $schedulable['allDay'] = $message->alldayevent;
  533. $schedulable['description'] = $message->body;
  534. $schedulable['dtstamp'] = $message->dtstamp;
  535. $schedulable['lastUpdate'] = time() * 1000;
  536. $schedulable['type'] = '1';
  537. if(isset($message->recurrence))
  538. {
  539. $repeatID = isset($schedulable['repeat']) ? $schedulable['repeat']['id'] : mt_rand() . '3(Formatter)';
  540. $repeat = array();
  541. $repeat['schedulable'] = $eventID;
  542. switch( $message->recurrence->type )
  543. {
  544. case 0:
  545. $repeat['frequency'] = 'daily';
  546. break;
  547. case 1:
  548. $repeat['frequency'] = 'weekly';
  549. break;
  550. case 2:
  551. $repeat['frequency'] = 'monthly';
  552. break;
  553. case 5:
  554. $repeat['frequency'] = 'yearly';
  555. break;
  556. }
  557. if(isset($message->recurrence->until))
  558. $repeat['endTime'] = $message->recurrence->until * 1000 ;
  559. else
  560. $repeat['endTime'] = null;
  561. $repeat['startTime'] = $message->starttime * 1000 ;
  562. $repeat['interval'] = isset($message->recurrence->interval) ? $message->recurrence->interval : 1;
  563. if(isset($message->recurrence->occurrences) && $message->recurrence->occurrences > 0)
  564. $repeat["count"] = $message->recurrence->occurrences;
  565. else
  566. $repeat["count"] = 0;
  567. if(isset($message->recurrence->weekofmonth) && $message->recurrence->weekofmonth > 0)
  568. $repeat["byweekno"] = $message->recurrence->weekofmonth;
  569. else
  570. $repeat["byweekno"] = 0;
  571. if(isset($message->recurrence->dayofmonth) && $message->recurrence->dayofmonth > 0)
  572. $repeat["bymonthday"] = $message->recurrence->dayofmonth;
  573. else
  574. $repeat["bymonthday"] = 0;
  575. $day = $message->recurrence->dayofweek;
  576. $day_of_week_array = array();
  577. if (($day & 1) > 0) $day_of_week_array[] = 'SU';
  578. if (($day & 2) > 0) $day_of_week_array[] = 'MO';
  579. if (($day & 4) > 0) $day_of_week_array[] = 'TU';
  580. if (($day & 8) > 0) $day_of_week_array[] = 'WE';
  581. if (($day & 16) > 0) $day_of_week_array[] = 'TH';
  582. if (($day & 32) > 0) $day_of_week_array[] = 'FR';
  583. if (($day & 64) > 0) $day_of_week_array[] = 'SA';
  584. $repeat["byday"] = implode(',' ,$day_of_week_array);
  585. $interation['repeat://' . $repeatID] = $repeat;
  586. }
  587. else if (isset($schedulable['repeat']) )
  588. {
  589. $interation['repeat://'.$schedulable['repeat']['id']] = null;
  590. }
  591. $partForDelete = $schedulable['participants'];
  592. foreach($partForDelete as $partForDeleteIndice => $partForDeleteValue)
  593. {
  594. if($partForDeleteValue['isOrganizer'] == '1')
  595. {
  596. if(isset($message->reminder) && $message->reminder > 0)
  597. {
  598. $alarm = array();
  599. $alarmID = isset($partForDeleteValue['alarms'][0]['id']) ? $partForDeleteValue['alarms'][0]['id'] : mt_rand() . '6(Formatter)';
  600. $alarm['type'] = 'alert';
  601. $alarm['time'] = $message->reminder;
  602. $alarm['unit'] = 'm';
  603. foreach ($interation as $iint => &$vint)
  604. {
  605. if(isset($vint['user']) && $vint['user'] == $this->_uidnumber)
  606. {
  607. $alarm['participant'] = str_replace('participant://', '', $iint);
  608. $vint['alarms'][] = $alarmID;
  609. }
  610. }
  611. $alarm['schedulable'] = $eventID;
  612. $interation['alarm://' . $alarmID ] = $alarm;
  613. }
  614. else if(isset($partForDeleteValue['alarms'][0]['id']))
  615. $interation['alarm://' . $partForDeleteValue['alarms'][0]['id'] ] = false;
  616. unset($partForDelete[$partForDeleteIndice]);
  617. unset($schedulable['participants'][$partForDeleteIndice]['alarms']);
  618. }
  619. }
  620. if(isset($message->attendees) && count($message->attendees) > 0)
  621. {
  622. foreach($message->attendees as $attendee)
  623. {
  624. if($this->_getParticipantByMail($attendee->email, $schedulable['participants']) === false)
  625. {
  626. $participantID = mt_rand() . '2(Formatter)';
  627. $participant = array();
  628. $participant['schedulable'] = $eventID;
  629. $participant['isOrganizer'] = '0';
  630. $participant['acl'] = 'r';
  631. /* Verifica se este usuario é um usuario interno do ldap */
  632. $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $attendee->email), array('=', 'mailAlternateAddress', $attendee->email))));
  633. $user = null;
  634. if ($intUser && count($intUser) > 0) {
  635. $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
  636. $participant['user'] = $intUser[0]['id'];
  637. } else {
  638. $participant['isExternal'] = 1;
  639. /* Gera um randon id para o contexto formater */
  640. $userID = mt_rand() . '4(Formatter)';
  641. $user['mail'] = $attendee->email;
  642. $user['name'] = ( isset($attendee->name) ) ? $attendee->name : '';
  643. $user['participants'] = array($participantID);
  644. $user['isExternal'] = '1';
  645. $participant['user'] = $userID;
  646. $interation['user://' . $userID] = $user;
  647. }
  648. $interation['participant://' . $participantID] = $participant;
  649. $schedulable['participants'][] = $participantID;
  650. }
  651. else
  652. unset($partForDelete[$this->_getParticipantByMail($attendee->email, $schedulable['participants'])]);
  653. }
  654. }
  655. foreach( $partForDelete as $toDelete)
  656. {
  657. $interation['participant://' . $toDelete['id']] = false;
  658. foreach ($schedulable['participants'] as $ipart => $part)
  659. {
  660. if($part['id'] == $toDelete['id'])
  661. {
  662. unset($schedulable['participants'][$ipart]);
  663. }
  664. }
  665. $schedulable['participants'] = array_merge($schedulable['participants'] , array());
  666. }
  667. foreach($schedulable['participants'] as $i => $v)
  668. {
  669. if($v['user']['id'] == $this->_uidnumber )
  670. {
  671. $schedulable['participants'][$i]['status'] = $this->formatBusy($message->busystatus);
  672. }
  673. }
  674. unset($schedulable['repeat']);
  675. $interation['schedulable://' . $eventID] = $schedulable;
  676. ob_start();
  677. $args = $interation;
  678. include EXPRESSO_PATH.'/prototype/Sync.php';
  679. ob_end_clean();
  680. return $this->StatMessage($folderid, $message->uid);
  681. }
  682. private function createEvent($folderid, $idMessage, $message , $calendar)
  683. {
  684. $tz_CEL = $this->_getTZFromSyncBlob(base64_decode($message->timezone));
  685. $GMT_CEL = -(($tz_CEL["bias"] + $tz_CEL["dstbias"]) * 60);
  686. $interation = array();
  687. $schedulable = array();
  688. $eventID = mt_rand() . '(Formatter)';
  689. $schedulable['calendar'] = $calendar['id'];
  690. $schedulable['uid'] = $message->uid;
  691. $schedulable['summary'] = $message->subject;
  692. $schedulable['location'] = $message->location;
  693. $schedulable['class'] = 1;
  694. /// Eliminana o timezone, enviado pelo ceulular e coloca no timezone do calendario.
  695. // o celular não manda o nome do timezone apenas o offset dele dae não tem como saber qual foi o timezone selecionado.
  696. $calendarSignatureTimezone = new DateTimeZone($calendar['timezone']) ;
  697. $schedulable['startTime'] = (($message->starttime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->starttime + $GMT_CEL), new DateTimeZone('UTC'))) * -1) ) *1000; //$message->starttime * 1000;
  698. $schedulable['endTime'] = (($message->endtime + $GMT_CEL) + ($calendarSignatureTimezone->getOffset(new DateTime('@'.($message->endtime + $GMT_CEL), new DateTimeZone('UTC')))* -1)) *1000;//$message->endtime * 1000;
  699. $sv = new DateTime('@'.($message->starttime + $GMT_CEL), $calendarSignatureTimezone);
  700. if($sv->format('I') == 0)
  701. $schedulable['startTime'] = $schedulable['startTime'] - 3600000;
  702. $ev = new DateTime('@'.($message->endtime + $GMT_CEL), $calendarSignatureTimezone);
  703. if($ev->format('I') == 0)
  704. $schedulable['endTime'] = $schedulable['endTime'] - 3600000;
  705. $schedulable['timezone'] = $calendar['timezone'];
  706. $schedulable['allDay'] = $message->alldayevent;
  707. $schedulable['description'] = $message->body;
  708. $schedulable['dtstamp'] = $message->dtstamp;
  709. // $schedulable['lastUpdate'] = 0;
  710. $schedulable['type'] = '1';
  711. $participant = array();
  712. $participantID = mt_rand() . '2(Formatter)';
  713. $participant['schedulable'] = $eventID;
  714. $participant['isOrganizer'] = '1';
  715. $participant['acl'] = 'rowi';
  716. $participant['status'] = '1';
  717. if($message->organizeremail)
  718. {
  719. /* Verifica se este usuario é um usuario interno do ldap */
  720. $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $message->organizeremail), array('=', 'mailAlternateAddress', $message->organizeremail))));
  721. $user = null;
  722. if ($intUser && count($intUser) > 0) {
  723. $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
  724. $participant['user'] = $intUser[0]['id'];
  725. } else {
  726. $participant['isExternal'] = 1;
  727. /* Gera um randon id para o contexto formater */
  728. $userID = mt_rand() . '4(Formatter)';
  729. $user['mail'] = $message->organizeremail;
  730. $user['name'] = ( isset($message->organizername) ) ? $message->organizername : '';
  731. $user['participants'] = array($participantID);
  732. $user['isExternal'] = '1';
  733. $participant['user'] = $userID;
  734. $interation['user://' . $userID] = $user;
  735. }
  736. }
  737. else
  738. {
  739. $participant['isExternal'] = 0;
  740. $participant['user'] = $this->_uidnumber;
  741. $participant['status'] = $this->formatBusy($message->busystatus);
  742. }
  743. //Caso exista recorrencias
  744. if(isset($message->recurrence))
  745. {
  746. /* Gera um randon id para o contexto formater */
  747. $repeatID = mt_rand() . '3(Formatter)';
  748. $repeat = array();
  749. $repeat['schedulable'] = $eventID;
  750. switch( $message->recurrence->type )
  751. {
  752. case 0:
  753. $repeat['frequency'] = 'daily';
  754. break;
  755. case 1:
  756. $repeat['frequency'] = 'weekly';
  757. break;
  758. case 2:
  759. $repeat['frequency'] = 'monthly';
  760. break;
  761. case 5:
  762. $repeat['frequency'] = 'yearly';
  763. break;
  764. }
  765. if(isset($message->recurrence->until))
  766. $repeat['endTime'] = $message->recurrence->until * 1000 ;
  767. $repeat['startTime'] = $message->starttime * 1000 ;
  768. $repeat['interval'] = isset($message->recurrence->interval) ? $message->recurrence->interval : 1;
  769. if(isset($message->recurrence->occurrences) && $message->recurrence->occurrences > 0)
  770. $repeat["count"] = $message->recurrence->occurrences;
  771. if(isset($message->recurrence->weekofmonth) && $message->recurrence->weekofmonth > 0)
  772. $repeat["byweekno"] = $message->recurrence->weekofmonth;
  773. if(isset($message->recurrence->dayofmonth) && $message->recurrence->dayofmonth > 0)
  774. $repeat["bymonthday"] = $message->recurrence->dayofmonth;
  775. $day = $message->recurrence->dayofweek;
  776. $day_of_week_array = array();
  777. if (($day & 1) > 0) $day_of_week_array[] = 'SU';
  778. if (($day & 2) > 0) $day_of_week_array[] = 'MO';
  779. if (($day & 4) > 0) $day_of_week_array[] = 'TU';
  780. if (($day & 8) > 0) $day_of_week_array[] = 'WE';
  781. if (($day & 16) > 0) $day_of_week_array[] = 'TH';
  782. if (($day & 32) > 0) $day_of_week_array[] = 'FR';
  783. if (($day & 64) > 0) $day_of_week_array[] = 'SA';
  784. $repeat["byday"] = implode(',' ,$day_of_week_array);
  785. $interation['repeat://' . $repeatID] = $repeat;
  786. }
  787. $interation['participant://' . $participantID] = $participant;
  788. $schedulable['participants'][] = $participantID;
  789. if(isset($message->attendees) && count($message->attendees) > 0)
  790. {
  791. foreach($message->attendees as $attendee)
  792. {
  793. $participantID = mt_rand() . '2(Formatter)';
  794. $participant = array();
  795. $participant['schedulable'] = $eventID;
  796. $participant['isOrganizer'] = '0';
  797. $participant['acl'] = 'r';
  798. /* Verifica se este usuario é um usuario interno do ldap */
  799. $intUser = Controller::find(array('concept' => 'user'), array('id', 'isExternal'), array('filter' => array('OR', array('=', 'mail', $attendee->email), array('=', 'mailAlternateAddress', $attendee->email))));
  800. $user = null;
  801. if ($intUser && count($intUser) > 0) {
  802. $participant['isExternal'] = isset($intUser[0]['isExternal']) ? $intUser[0]['isExternal'] : 0;
  803. $participant['user'] = $intUser[0]['id'];
  804. } else {
  805. $participant['isExternal'] = 1;
  806. /* Gera um randon id para o contexto formater */
  807. $userID = mt_rand() . '4(Formatter)';
  808. $user['mail'] = $attendee->email;
  809. $user['name'] = ( isset($attendee->name) ) ? $attendee->name : '';
  810. $user['participants'] = array($participantID);
  811. $user['isExternal'] = '1';
  812. $participant['user'] = $userID;
  813. $interation['user://' . $userID] = $user;
  814. if($userID == $this->_uidnumber)
  815. {
  816. $participant['status'] = $this->formatBusy($message->busystatus);
  817. }
  818. }
  819. $interation['participant://' . $participantID] = $participant;
  820. $schedulable['participants'][] = $participantID;
  821. }
  822. }
  823. if(isset($message->reminder) && $message->reminder > 0)
  824. {
  825. $alarm = array();
  826. $alarmID = mt_rand() . '6(Formatter)';
  827. $alarm['type'] = 'alert';
  828. $alarm['time'] = $message->reminder;
  829. $alarm['unit'] = 'm';
  830. foreach ($interation as $iint => &$vint)
  831. {
  832. if(isset($vint['user']) && $vint['user'] == $this->_uidnumber)
  833. {
  834. $alarm['participant'] = str_replace('participant://', '', $iint);
  835. $vint['alarms'][] = $alarmID;
  836. }
  837. }
  838. $alarm['schedulable'] = $eventID;
  839. $interation['alarm://' . $alarmID ] = $alarm;
  840. }
  841. $interation['schedulable://' . $eventID] = $schedulable;
  842. ob_start();
  843. $args = $interation;
  844. include EXPRESSO_PATH.'/prototype/Sync.php';
  845. ob_end_clean();
  846. return $this->StatMessage($folderid, $message->uid);
  847. }
  848. /**
  849. * Changes the 'read' flag of a message on disk. The $flags
  850. * parameter can only be '1' (read) or '0' (unread). After a call to
  851. * SetReadFlag(), GetMessageList() should return the message with the
  852. * new 'flags' but should not modify the 'mod' parameter. If you do
  853. * change 'mod', simply setting the message to 'read' on the mobile will trigger
  854. * a full resync of the item from the server.
  855. *
  856. * @param string $folderid id of the folder
  857. * @param string $id id of the message
  858. * @param int $flags read flag of the message
  859. *
  860. * @access public
  861. * @return boolean status of the operation
  862. * @throws StatusException could throw specific SYNC_STATUS_* exceptions
  863. */
  864. public function SetReadFlag($folderid, $id, $flags, $contentParameters)
  865. {
  866. return true;
  867. }
  868. /**
  869. * Called when the user has requested to delete (really delete) a message. Usually
  870. * this means just unlinking the file its in or somesuch. After this call has succeeded, a call to
  871. * GetMessageList() should no longer list the message. If it does, the message will be re-sent to the mobile
  872. * as it will be seen as a 'new' item. This means that if this method is not implemented, it's possible to
  873. * delete messages on the PDA, but as soon as a sync is done, the item will be resynched to the mobile
  874. *
  875. * @param string $folderid id of the folder
  876. * @param string $id id of the message
  877. *
  878. * @access public
  879. * @return boolean status of the operation
  880. * @throws StatusException could throw specific SYNC_STATUS_* exceptions
  881. */
  882. public function DeleteMessage($folderid, $id, $contentParameters)
  883. {
  884. $idNumber = (int)str_replace('calendar' , '' , $folderid);
  885. $calendarSignature = Controller::read( array( 'concept' => 'calendarSignature' , 'id' => $idNumber ));
  886. $even = $this->_getSchedulable($id );
  887. $calendar = Controller::read( array( 'concept' => 'calendar' , 'id' => $calendarSignature['calendar'] ));
  888. $link = Controller::read(array('concept' => 'calendarToSchedulable'), false, array('filter' => array('AND', array('=','calendar',$calendarSignature['calendar']), array('=','schedulable',$even['id']))));
  889. $delete = false;
  890. foreach($even['participants'] as $i => $v)
  891. {
  892. if($v['user']['id'] == $this->_uidnumber && $v['user']['isOrganizer'] == '1')
  893. {
  894. $delete = true;
  895. }
  896. }
  897. if( $delete === true)
  898. {
  899. Controller::delete(array('concept' => 'schedulable' , 'id' => $even['id']));
  900. }
  901. else
  902. {
  903. Controller::delete(array('concept' => 'calendarToSchedulable', 'id' => $link[0]['id']));
  904. foreach($even['participants'] as $i => $v)
  905. {
  906. if($v['user']['id'] == $this->_uidnumber)
  907. {
  908. Controller::update(array('concept' => 'participant','id' => $v['id']), array('status' => STATUS_CANCELLED ));
  909. }
  910. }
  911. }
  912. return true;
  913. }
  914. /**
  915. * Called when the user moves an item on the PDA from one folder to another. Whatever is needed
  916. * to move the message on disk has to be done here. After this call, StatMessage() and GetMessageList()
  917. * should show the items to have a new parent. This means that it will disappear from GetMessageList()
  918. * of the sourcefolder and the destination folder will show the new message
  919. *
  920. * @param string $folderid id of the source folder
  921. * @param string $id id of the message
  922. * @param string $newfolderid id of the destination folder
  923. *
  924. * @access public
  925. * @return boolean status of the operation
  926. * @throws StatusException could throw specific SYNC_MOVEITEMSSTATUS_* exceptions
  927. */
  928. public function MoveMessage($folderid, $id, $newfolderid , $contentParameters)
  929. {
  930. return false;
  931. }
  932. /**
  933. * Authenticates the user
  934. *
  935. * @param string $username
  936. * @param string $domain
  937. * @param string $password
  938. *
  939. * @access public
  940. * @return boolean
  941. * @throws FatalException e.g. some required libraries are unavailable
  942. */
  943. public function Logon($username, $domain, $password)
  944. {
  945. $ldapConfig = parse_ini_file(EXPRESSO_PATH . '/prototype/config/OpenLDAP.srv' , true );
  946. $ldapConfig = $ldapConfig['config'];
  947. $sr = ldap_search( $GLOBALS['connections']['ldap'] , $ldapConfig['context'] , "(uid=$username)" , array('uidNumber','uid','mail'), 0 , 1 );
  948. if(!$sr) return false;
  949. $entries = ldap_get_entries( $GLOBALS['connections']['ldap'] , $sr );
  950. $this->_uidnumber = $entries[0]['uidnumber'][0];
  951. //Inicia Variaveis de para API expresso
  952. if(!isset($_SESSION))
  953. session_start();
  954. $userWallet = array();
  955. $userWallet['uidNumber'] = $entries[0]['uidnumber'][0];
  956. $userWallet['uid'] = $entries[0]['uid'][0];
  957. $userWallet['mail'] = $entries[0]['mail'][0];
  958. $_SESSION['wallet'] = array();
  959. $_SESSION['wallet']['user'] = $userWallet;
  960. $_SESSION['flags']['currentapp'] = 'expressoCalendar';
  961. //----------------------------------------------------------------------------------------//
  962. return true;
  963. }
  964. /**
  965. * Logs off
  966. * non critical operations closing the session should be done here
  967. *
  968. * @access public
  969. * @return boolean
  970. */
  971. public function Logoff()
  972. {
  973. }
  974. /**
  975. * Sends an e-mail
  976. * This messages needs to be saved into the 'sent items' folder
  977. *
  978. * Basically two things can be done
  979. * 1) Send the message to an SMTP server as-is
  980. * 2) Parse the message, and send it some other way
  981. *
  982. * @param SyncSendMail $sm Sy…

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