source: trunk/calendar/inc/class.bocalendar.inc.php @ 7681

Revision 7681, 163.5 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Correcoes para Best Practice: Short Open Tag e Best Practice: Always Quote Array Keys.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2  /**************************************************************************\
3  * eGroupWare - Calendar                                                    *
4  * http://www.eGroupWare.org                                                *
5  * Maintained and further developed by RalfBecker@outdoor-training.de       *
6  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
7  *          http://www.radix.net/~cknudsen                                  *
8  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
9  * --------------------------------------------                             *
10  *  This program is free software; you can redistribute it and/or modify it *
11  *  under the terms of the GNU General Public License as published by the   *
12  *  Free Software Foundation; either version 2 of the License, or (at your  *
13  *  option) any later version.                                              *
14  \**************************************************************************/
15
16
17        class bocalendar
18        {
19                var $public_functions = Array(
20                        'read_entry'      => True,
21                        'delete_entry'    => True,
22                        'delete_calendar' => True,
23                        'change_owner'    => True,
24                        'update'          => True,
25                        'check_set_default_prefs' => True,
26                        'store_to_cache'  => True,
27                        'export_event'    => True,
28                        'send_alarm'      => True,
29                        'reinstate'       => True
30                );
31
32                var $soap_functions = Array(
33                        'read_entry' => Array(
34                                'in' => Array(
35                                        'int'
36                                ),
37                                'out' => Array(
38                                        'SOAPStruct'
39                                )
40                        ),
41                        'delete_entry' => Array(
42                                'in' => Array(
43                                        'int'
44                                ),
45                                'out' => Array(
46                                        'int'
47                                )
48                        ),
49                        'delete_calendar' => Array(
50                                'in' => Array(
51                                        'int'
52                                ),
53                                'out' => Array(
54                                        'int'
55                                )
56                        ),
57                        'change_owner' => Array(
58                                'in' => Array(
59                                        'array'
60                                ),
61                                'out' => Array(
62                                        'int'
63                                )
64                        ),
65                        'update' => Array(
66                                'in' => Array(
67                                        'array',
68                                        'array',
69                                        'array',
70                                        'array',
71                                        'array'
72                                ),
73                                'out' => Array(
74                                        'array'
75                                )
76                        ),
77                        'store_to_cache'        => Array(
78                                'in' => Array(
79                                        'struct'
80                                ),
81                                'out' => Array(
82                                        'SOAPStruct'
83                                )
84                        ),
85                        'store_to_cache'        => Array(
86                                'in' => Array(
87                                        'array'
88                                ),
89                                'out' => Array(
90                                        'string'
91                                )
92                        ),
93                        'categories' => array(
94                                'in'  => array('bool'),
95                                'out' => array('array')
96                        ),
97                );
98
99                var $debug = False;
100//              var $debug = True;
101
102                var $so;
103                var $so1;
104                var $ex_participants;
105                var $cached_events;
106                var $repeating_events;
107                var $day;
108                var $month;
109                var $year;
110                var $prefs;
111                var $wdays;
112                var $owner;
113                var $holiday_color;
114                var $printer_friendly = False;
115                var $repetido;
116                var $cached_holidays;
117
118                var $g_owner = 0;
119
120                var $filter;
121                var $cat_id;
122                var $users_timeformat;
123
124                var $modified;
125                var $deleted;
126                var $added;
127
128                var $is_group = False;
129
130                var $soap = False;
131
132                var $use_session = False;
133
134                var $today;
135                var $debug_string;
136
137                var $sortby;
138                var $num_months;
139                var $xmlrpc = False;    // not called via xmlrpc
140        var $async = false;
141
142                var $alreadyNotifieds;
143                var $alreadyExtNotifieds = array();
144               
145                var $extAdded;
146                var $extDeleted;
147               
148                function bocalendar($session=0)
149                {
150
151                        if(!is_object($GLOBALS['phpgw']->datetime))
152                        {
153                                $GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
154                        }
155
156                        $this->cat = CreateObject('phpgwapi.categories');
157                        $this->grants = $GLOBALS['phpgw']->acl->get_grants('calendar');
158                        @reset($this->grants);
159                        if(DEBUG_APP)
160                        {
161                                if(floor(phpversion()) >= 4)
162                                {
163                                        $this->debug_string = '';
164                                        ob_start();
165                                }
166
167                                foreach($this->grants as $grantor => $rights)
168                                {
169                                        print_debug('Grantor',$grantor);
170                                        print_debug('Rights',$rights);
171                                }
172                        }
173
174                        print_debug('Read use_session',$session);
175
176                        if($session)
177                        {
178                                $this->read_sessiondata();
179                                $this->use_session = True;
180                        }
181                        print_debug('BO Filter',$this->filter);
182                        print_debug('Owner',$this->owner);
183
184                        if ($GLOBALS['argv']) {
185                          $this->async = true;
186                          $this->load_lang();
187                        }
188
189                        $this->prefs['calendar']    = $GLOBALS['phpgw_info']['user']['preferences']['calendar'];
190                        $this->check_set_default_prefs();
191
192                        $owner = get_var('owner',array('GET','POST'),$GLOBALS['owner']);
193
194                        preg_match('/menuaction=([a-zA-Z.]+)/',$_SERVER['HTTP_REFERER'],$regs);
195                        $from = $regs[1];
196                        if ((substr($_SERVER['PHP_SELF'],-8) == 'home.php' && substr($this->prefs['calendar']['defaultcalendar'],0,7) == 'planner'
197                                || $_GET['menuaction'] == 'calendar.uicalendar.planner' &&
198                                $from  != 'calendar.uicalendar.planner' && !$this->save_owner)
199                                && (int)$this->prefs['calendar']['planner_start_with_group'] > 0)
200                        {
201                                // entering planner for the first time ==> saving owner in save_owner, setting owner to default
202                                //
203                                $this->save_owner = $this->owner;
204                                $owner = 'g_'.$this->prefs['calendar']['planner_start_with_group'];
205                        }
206                        elseif ($_GET['menuaction'] != 'calendar.uicalendar.planner' &&
207                                $this->save_owner)
208                        {
209                                // leaving planner with an unchanged user/owner ==> setting owner back to save_owner
210                                //
211                                $owner = (int)(isset($_GET['owner']) ? $_GET['owner'] : $this->save_owner);
212                                unset($this->save_owner);
213                        }
214                        elseif (!empty($owner) && $owner != $this->owner && $from == 'calendar.uicalendar.planner')
215                        {
216                                // user/owner changed within planner ==> forgetting save_owner
217                                //
218                                unset($this->save_owner);
219                        }
220
221                        if(isset($owner) && $owner!='' && substr($owner,0,2) == 'g_')
222                        {
223                                $this->set_owner_to_group(substr($owner,2));
224                        }
225                        elseif(isset($owner) && $owner!='')
226                        {
227                                $this->owner = (int)$owner;
228                        }
229                        elseif(!@isset($this->owner) || !@$this->owner)
230                        {
231                                $this->owner = (int)$GLOBALS['phpgw_info']['user']['account_id'];
232                        }
233                        elseif(isset($this->owner) && $GLOBALS['phpgw']->accounts->get_type($this->owner) == 'g')
234                        {
235                                $this->set_owner_to_group((int)$this->owner);
236                        }
237
238                        $this->prefs['common']    = $GLOBALS['phpgw_info']['user']['preferences']['common'];
239
240                        if ($this->prefs['common']['timeformat'] == '12')
241                        {
242                                $this->users_timeformat = 'h:ia';
243                        }
244                        else
245                        {
246                                $this->users_timeformat = 'H:i';
247                        }
248                        $this->holiday_color = (substr($GLOBALS['phpgw_info']['theme']['bg07'],0,1)=='#'?'':'#').$GLOBALS['phpgw_info']['theme']['bg07'];
249
250                        $friendly = (isset($_GET['friendly'])?$_GET['friendly']:'');
251                        $friendly = ($friendly=='' && isset($_POST['friendly'])?$_POST['friendly']:$friendly);
252
253                        $this->printer_friendly = ((int)$friendly == 1?True:False);
254
255                        if(isset($_POST['filter'])) { $this->filter = $_POST['filter']; }
256                        if(isset($_POST['sortby'])) { $this->sortby = $_POST['sortby']; }
257                        if(isset($_POST['cat_id'])) { $this->cat_id = $_POST['cat_id']; }
258
259                        if(!isset($this->filter))
260                        {
261                                $this->filter = ' '.$this->prefs['calendar']['defaultfilter'].' ';
262                        }
263
264                        if(!isset($this->sortby))
265                        {
266                                $this->sortby = $this->prefs['calendar']['defaultcalendar'] == 'planner_user' ? 'user' : 'category';
267                        }
268
269                        if($GLOBALS['phpgw']->accounts->get_type($this->owner)=='g')
270                        {
271                                $this->filter = ' all ';
272                        }
273
274                        $this->so = CreateObject('calendar.socalendar',
275                                Array(
276                                        'owner'         => $this->owner,
277                                        'filter'        => $this->filter,
278                                        'category'      => $this->cat_id,
279                                        'g_owner'       => $this->g_owner
280                                )
281                        );
282                        $this->rpt_day = array( // need to be after creation of socalendar
283                                MCAL_M_SUNDAY    => 'Sunday',
284                                MCAL_M_MONDAY    => 'Monday',
285                                MCAL_M_TUESDAY   => 'Tuesday',
286                                MCAL_M_WEDNESDAY => 'Wednesday',
287                                MCAL_M_THURSDAY  => 'Thursday',
288                                MCAL_M_FRIDAY    => 'Friday',
289                                MCAL_M_SATURDAY  => 'Saturday'
290                        );
291                        if($this->bo->prefs['calendar']['weekdaystarts'] != 'Sunday')
292                        {
293                                $mcals = array_keys($this->rpt_day);
294                                $days  = array_values($this->rpt_day);
295                                $this->rpt_day = array();
296                                list($n) = $found = array_keys($days,$this->prefs['calendar']['weekdaystarts']);
297                                for ($i = 0; $i < 7; ++$i,++$n)
298                                {
299                                        $this->rpt_day[$mcals[$n % 7]] = $days[$n % 7];
300                                }
301                        }
302                        $this->rpt_type = Array(
303                                MCAL_RECUR_NONE         => 'None',
304                                MCAL_RECUR_DAILY        => 'Daily',
305                                MCAL_RECUR_WEEKLY       => 'Weekly',
306                                MCAL_RECUR_MONTHLY_WDAY => 'Monthly (by day)',
307                                MCAL_RECUR_MONTHLY_MDAY => 'Monthly (by date)',
308                                MCAL_RECUR_YEARLY       => 'Yearly'
309                        );
310
311                        $localtime = $GLOBALS['phpgw']->datetime->users_localtime;
312
313                        $date = (isset($GLOBALS['date'])?$GLOBALS['date']:'');
314                        $date = (isset($_GET['date'])?$_GET['date']:$date);
315                        $date = ($date=='' && isset($_POST['date'])?$_POST['date']:$date);
316
317                        $year = (isset($_GET['year'])?$_GET['year']:'');
318                        $year = ($year=='' && isset($_POST['year'])?$_POST['year']:$year);
319
320                        $month = (isset($_GET['month'])?$_GET['month']:'');
321                        $month = ($month=='' && isset($_POST['month'])?$_POST['month']:$month);
322
323                        $day = (isset($_GET['day'])?$_GET['day']:'');
324                        $day = ($day=='' && isset($_POST['day'])?$_POST['day']:'');
325
326                        $num_months = (isset($_GET['num_months'])?$_GET['num_months']:'');
327                        $num_months = ($num_months=='' && isset($_POST['num_months'])?$_POST['num_months']:$num_months);
328
329                        if(isset($date) && $date!='')
330                        {
331                                $this->year  = (int)(substr($date,0,4));
332                                $this->month = (int)(substr($date,4,2));
333                                $this->day   = (int)(substr($date,6,2));
334                        }
335                        else
336                        {
337                                if(isset($year) && $year!='')
338                                {
339                                        $this->year = $year;
340                                }
341                                else
342                                {
343                                        $this->year = date('Y',$localtime);
344                                }
345                                if(isset($month) && $month!='')
346                                {
347                                        $this->month = $month;
348                                }
349                                else
350                                {
351                                        $this->month = date('m',$localtime);
352                                }
353                                if(isset($day) && $day!='')
354                                {
355                                        $this->day = $day;
356                                }
357                                else
358                                {
359                                        $this->day = date('d',$localtime);
360                                }
361                        }
362
363                        if(isset($num_months) && $num_months!='')
364                        {
365                                $this->num_months = $num_months;
366                        }
367                        elseif($this->num_months == 0)
368                        {
369                                $this->num_months = 1;
370                        }
371
372                        $this->today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
373
374                        if(DEBUG_APP)
375                        {
376                                print_debug('BO Filter','('.$this->filter.')');
377                                print_debug('Owner',$this->owner);
378                                print_debug('Today',$this->today);
379                                if(floor(phpversion()) >= 4)
380                                {
381                                        $this->debug_string .= ob_get_contents();
382                                        ob_end_clean();
383                                }
384                        }
385                        $this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
386                        $this->wdays = Array(MCAL_M_SUNDAY,MCAL_M_MONDAY,MCAL_M_TUESDAY,MCAL_M_WEDNESDAY,
387                            MCAL_M_THURSDAY,MCAL_M_FRIDAY,MCAL_M_SATURDAY);
388                }
389
390          function load_lang() {
391            if(!$_SESSION['phpgw_info']['calendar']['langAlarm'])
392              {
393                $array_keys = array();
394                $fn = '../../calendar/setup/phpgw_alarm_'.$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'].'.lang';                     
395                echo $fn;
396                if (file_exists($fn)){
397                  $fp = fopen($fn,'r');
398                  while ($data = fgets($fp,16000))      {
399                    list($message_id,$app_name,$null,$content) = explode("\t",substr($data,0,-1));                     
400                    $_SESSION['phpgw_info']['calendar']['langAlarm'][$message_id] =  $content;
401                  }
402                  fclose($fp);
403                }
404              }
405          }
406                function list_methods($_type='xmlrpc')
407                {
408                        /*
409                          This handles introspection or discovery by the logged in client,
410                          in which case the input might be an array.  The server always calls
411                          this function to fill the server dispatch map using a string.
412                        */
413                        if (is_array($_type))
414                        {
415                                $_type = $_type['type'];
416                        }
417                        switch($_type)
418                        {
419                                case 'xmlrpc':
420                                        $xml_functions = array(
421                                                'list_methods' => array(
422                                                        'function'  => 'list_methods',
423                                                        'signature' => array(array(xmlrpcStruct,xmlrpcString)),
424                                                        'docstring' => lang('Read this list of methods.')
425                                                ),
426                                                'read' => array(
427                                                        'function'  => 'read_entry',
428                                                        'signature' => array(array(xmlrpcStruct,xmlrpcInt)),
429                                                        'docstring' => lang('Read a single entry by passing the id and fieldlist.')
430                                                ),
431                                                'read_entry' => array(  // deprecated, use read
432                                                        'function'  => 'read_entry',
433                                                        'signature' => array(array(xmlrpcStruct,xmlrpcInt)),
434                                                        'docstring' => lang('Read a single entry by passing the id and fieldlist.')
435                                                ),
436                                                'write' => array(
437                                                        'function'  => 'update',
438                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
439                                                        'docstring' => lang('Add or update a single entry by passing the fields.')
440                                                ),
441                                                'add_entry' => array(   // deprecated, use write
442                                                        'function'  => 'update',
443                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
444                                                        'docstring' => lang('Add a single entry by passing the fields.')
445                                                ),
446                                                'update_entry' => array(        // deprecated, use write
447                                                        'function'  => 'update',
448                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
449                                                        'docstring' => lang('Update a single entry by passing the fields.')
450                                                ),
451                                                'delete' => array(
452                                                        'function'  => 'delete_entry',
453                                                        'signature' => array(array(xmlrpcInt,xmlrpcInt)),
454                                                        'docstring' => lang('Delete a single entry by passing the id.')
455                                                ),
456                                                'delete_entry' => array(        // deprecated, use delete
457                                                        'function'  => 'delete_entry',
458                                                        'signature' => array(array(xmlrpcInt,xmlrpcInt)),
459                                                        'docstring' => lang('Delete a single entry by passing the id.')
460                                                ),
461                                                'delete_calendar' => array(
462                                                        'function'  => 'delete_calendar',
463                                                        'signature' => array(array(xmlrpcInt,xmlrpcInt)),
464                                                        'docstring' => lang('Delete an entire users calendar.')
465                                                ),
466                                                'change_owner' => array(
467                                                        'function'  => 'change_owner',
468                                                        'signature' => array(array(xmlrpcInt,xmlrpcStruct)),
469                                                        'docstring' => lang('Change all events for $params[\'old_owner\'] to $params[\'new_owner\'].')
470                                                ),
471                                                'search' => array(
472                                                        'function'  => 'store_to_cache',
473                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
474                                                        'docstring' => lang('Read a list of entries.')
475                                                ),
476                                                'store_to_cache' => array(      // deprecated, use search
477                                                        'function'  => 'store_to_cache',
478                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
479                                                        'docstring' => lang('Read a list of entries.')
480                                                ),
481                                                'export_event' => array(
482                                                        'function'  => 'export_event',
483                                                        'signature' => array(array(xmlrpcString,xmlrpcStruct)),
484                                                        'docstring' => lang('Export a list of entries in iCal format.')
485                                                ),
486                                                'categories' => array(
487                                                        'function'  => 'categories',
488                                                        'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
489                                                        'docstring' => lang('List all categories.')
490                                                ),
491                                        );
492                                        return $xml_functions;
493                                        break;
494                                case 'soap':
495                                        return $this->soap_functions;
496                                        break;
497                                default:
498                                        return array();
499                                        break;
500                        }
501                }
502
503                function set_owner_to_group($owner)
504                {
505                        print_debug('calendar::bocalendar::set_owner_to_group:owner',$owner);
506                        $this->owner = (int)$owner;
507                        $this->is_group = True;
508                        $this->g_owner = Array();
509                        $members = $GLOBALS['phpgw']->accounts->member($owner);
510                        if (is_array($members))
511                        {
512                                foreach($members as $user)
513                                {
514                                        // use only members which gave the user a read-grant
515                                        if ($this->check_perms(PHPGW_ACL_READ,0,$user['account_id']))
516                                        {
517                                                $this->g_owner[] = $user['account_id'];
518                                        }
519                                }
520                        }
521                        //echo "<p>".function_backtrace().": set_owner_to_group($owner) = ".print_r($this->g_owner,True)."</p>\n";
522                }
523
524                function member_of_group($owner=0)
525                {
526                        $owner = ($owner==0?$GLOBALS['phpgw_info']['user']['account_id']:$owner);
527                        $group_owners = $GLOBALS['phpgw']->accounts->membership();
528                        while($group_owners && list($index,$group_info) = each($group_owners))
529                        {
530                                if($this->owner == $group_info['account_id'])
531                                {
532                                        return True;
533                                }
534                        }
535                        return False;
536                }
537
538                function save_sessiondata($data='')
539                {
540                        if ($this->use_session)
541                        {
542                                if (!is_array($data))
543                                {
544                                        $data = array(
545                                                'filter'     => $this->filter,
546                                                'cat_id'     => $this->cat_id,
547                                                'owner'      => $this->owner,
548                                                'save_owner' => $this->save_owner,
549                                                'year'       => $this->year,
550                                                'month'      => $this->month,
551                                                'day'        => $this->day,
552                                                'date'       => $this->date,
553                                                'sortby'     => $this->sortby,
554                                                'num_months' => $this->num_months,
555                                                'return_to'  => $this->return_to
556                                        );
557                                }
558                                if($this->debug)
559                                {
560                                        if(floor(phpversion()) >= 4)
561                                        {
562                                                ob_start();
563                                        }
564                                        echo '<!-- '."\n".'Save:'."\n"._debug_array($data,False)."\n".' -->'."\n";
565                                        if(floor(phpversion()) >= 4)
566                                        {
567                                                $this->debug_string .= ob_get_contents();
568                                                ob_end_clean();
569                                        }
570                                }
571                                $GLOBALS['phpgw']->session->appsession('session_data','calendar',$data);
572                        }
573                }
574
575                function read_sessiondata()
576                {
577                        $data = $GLOBALS['phpgw']->session->appsession('session_data','calendar');
578                        print_debug('Read',_debug_array($data,False));
579
580                        $this->filter = $data['filter'];
581                        $this->cat_id = $data['cat_id'];
582                        $this->sortby = $data['sortby'];
583                        $this->owner  = (int)$data['owner'];
584                        $this->save_owner = (int)$data['save_owner'];
585                        $this->year   = (int)$data['year'];
586                        $this->month  = (int)$data['month'];
587                        $this->day    = (int)$data['day'];
588                        $this->num_months = (int)$data['num_months'];
589                        $this->return_to = $data['return_to'];
590                }
591
592                function read_entry($id,$ignore_acl=False)
593                {
594                        if (is_array($id) && count($id) == 1)
595                        {
596                                list(,$id) = each($id);
597                        }
598                        if($ignore_acl || $this->check_perms(PHPGW_ACL_READ,$id))
599                        {
600                                $event = $this->so->read_entry($id);
601                                if(!isset($event['participants'][$this->owner]) && $this->user_is_a_member($event,$this->owner))
602                                {
603                                        $this->so->add_attribute('participants','U',(int)$this->owner);
604                                        $this->so->add_entry($event);
605                                        $event = $this->get_cached_event();
606                                }
607                                return $this->xmlrpc ? $this->xmlrpc_prepare($event) : $event;
608                        }
609                        if ($this->xmlrpc)
610                        {
611                                $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
612                        }
613                        return False;
614                }
615
616                function delete_single($param)
617                {
618                        if($this->check_perms(PHPGW_ACL_DELETE,(int)$param['id']))
619                        {
620                                $temp_event = $this->get_cached_event();
621                                $event = $this->read_entry((int)$param['id']);
622//                              if($this->owner == $event['owner'])
623//                              {
624                                $exception_time = mktime($event['start']['hour'],$event['start']['min'],0,$param['month'],$param['day'],$param['year']) - $GLOBALS['phpgw']->datetime->tz_offset;
625                                $event['recur_exception'][] = (int)$exception_time;
626                                $this->so->cal->event = $event;
627//                              print_debug('exception time',$event['recur_exception'][count($event['recur_exception']) -1]);
628//                              print_debug('count event exceptions',count($event['recur_exception']));
629                                $this->so->add_entry($event,true,$event['owner']);
630                                $cd = 16;
631
632                                $this->so->cal->event = $temp_event;
633                                unset($temp_event);
634                        }
635                        else
636                        {
637                                $cd = 60;
638                        }
639//                      }
640                        return $cd;
641                }
642
643                function delete_entry($id)
644                {
645                        if (is_array($id) && count($id) == 1)
646                        {
647                                list(,$id) = each($id);
648                        }
649                        if($this->check_perms(PHPGW_ACL_DELETE,$id))
650                        {
651                                $this->so->delete_entry($id);
652
653                                if ($this->xmlrpc)
654                                {
655                                        $this->so->expunge($id);
656                                }
657                                return $this->xmlrpc ? True : 16;
658                        }
659                        if ($this->xmlrpc)
660                        {
661                                $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
662                        }
663                        return 60;
664                }
665
666                function reinstate($params='')
667                {
668                        if($this->check_perms(PHPGW_ACL_EDIT,$params['cal_id']) && isset($params['reinstate_index']))
669                        {
670                                $event = $this->so->read_entry($params['cal_id']);
671                                @reset($params['reinstate_index']);
672                                print_debug('Count of reinstate_index',count($params['reinstate_index']));
673                                if(count($params['reinstate_index']) > 1)
674                                {
675                                        while(list($key,$value) = each($params['reinstate_index']))
676                                        {
677                                                print_debug('reinstate_index ['.$key.']',(int)$value);
678                                                print_debug('exception time',$event['recur_exception'][(int)$value]);
679                                                unset($event['recur_exception'][(int)$value]);
680                                                print_debug('count event exceptions',count($event['recur_exception']));
681                                        }
682                                }
683                                else
684                                {
685                                        print_debug('reinstate_index[0]',(int)$params['reinstate_index'][0]);
686                                        print_debug('exception time',$event['recur_exception'][(int)$params['reinstate_index'][0]]);
687                                        unset($event['recur_exception'][(int)$params['reinstate_index'][0]]);
688                                        print_debug('count event exceptions',count($event['recur_exception']));
689                                }
690                                $this->so->cal->event = $event;
691                                $this->so->add_entry($event);
692                                return 42;
693                        }
694                        else
695                        {
696                                return 43;
697                        }
698                }
699
700                function delete_calendar($owner)
701                {
702                        if($GLOBALS['phpgw_info']['user']['apps']['admin'])
703                        {
704                                $this->so->delete_calendar($owner);
705                        }
706                }
707
708                function change_owner($params='')
709                {
710                        if($GLOBALS['phpgw_info']['server']['calendar_type'] == 'sql')
711                        {
712                                if(is_array($params))
713                                {
714                                        $this->so->change_owner($params['old_owner'],$params['new_owner']);
715                                }
716                        }
717                }
718
719                function expunge()
720                {
721                        reset($this->so->cal->deleted_events);
722                        while(list($i,$event_id) = each($this->so->cal->deleted_events))
723                        {
724                                $event = $this->so->read_entry($event_id);
725                                if(!$this->ex_participants)
726                                        $this->ex_participants = html_entity_decode($event['ex_participants']);                 
727                                if($this->check_perms(PHPGW_ACL_DELETE,$event))
728                                {
729                                        $this->send_update(MSG_DELETED,$event['participants'],$event,false,$event['owner']);
730                                }
731                                else
732                                {
733                                        unset($this->so->cal->deleted_events[$i]);
734                                }
735                        }
736                        $this->so->expunge();
737                }
738
739                function search_keywords($keywords)
740                {
741                        $type = $GLOBALS['phpgw']->accounts->get_type($this->owner);
742
743                        if($type == 'g')
744                        {
745                                $members = $GLOBALS['phpgw']->acl->get_ids_for_location($this->owner, 1, 'phpgw_group');
746                        }
747                        else
748                        {
749                                $members = array_keys($this->grants);
750
751                                if (!in_array($this->owner,$members))
752                                {
753                                        $members[] = $this->owner;
754                                }
755                        }
756                        foreach($members as $n => $uid)
757                        {
758                                if (!($this->grants[$uid] & PHPGW_ACL_READ))
759                                {
760                                        unset($members[$n]);
761                                }
762                        }
763                        return $this->so->list_events_keyword($keywords,$members);
764                }
765
766                function getNextDow($start){
767                    if ($start == 6)
768                    {
769                        return 0;
770                    }
771                    else
772                    {
773                        return $start + 1;
774                    }
775                }
776
777                // TODO: Levar em consideração no cálculo das ocorrências o parâmetro
778                // $event['recur_interval']
779                function expand_repetition($event){
780                    $return = Array();
781
782                    $event['recur_enddate']['hour'] = 24;
783                    $enddate = $this->maketime($event['recur_enddate']);
784
785                    $owner = $event['owner'];
786                    $participants = $event['participants'];
787
788
789                    switch($event['recur_type']) {
790                        case MCAL_RECUR_DAILY:
791                            // add 1 day = 86400 sec
792                            $starttime = $this->maketime($event['start']);
793                            $endtime = $this->maketime($event['end']);
794
795                            $offset = 86400;
796                            for (; $starttime <= $enddate;
797                                $starttime = $starttime+$offset,
798                                $endtime = $endtime+$offset)
799                            {
800                                $new_event = Array();
801                                $new_event['owner'] = $owner;
802                                $new_event['participants'] = $participants;
803                                $new_event['start'] = $starttime;
804                                $new_event['end'] = $endtime;
805                                $return[] = $new_event;
806                            }
807
808                            break;
809                        case MCAL_RECUR_WEEKLY:
810
811                            $setDow = (int)date('w',$this->maketime($event['start']));
812                            $dowOffsets = Array();
813                            $firstDow;
814                            $firstDowOffset = 0;
815
816                            // Initializing do
817                            $mask = $this->wdays[$setDow];
818                            $firstDayMismatch = False;
819                            if (((int)$event['recur_data'] & $mask) == 0){
820                                $firstDayMismatch = True;
821                            }
822
823                            $dow = $setDow;
824
825                            for ($nextDow = $setDow; array_sum($dowOffsets) < 7;)
826                            {
827
828                                $nextDow = $this->getNextDow($nextDow);
829                                $mask = $this->wdays[$nextDow];
830
831                                if (((int)$event['recur_data'] & $mask) != 0)
832                                {
833                                    if ($firstDayMismatch and $firstDowOffset == 0)
834                                    {
835                                        if ($dow < $nextDow)
836                                        {
837                                            $firstDowOffset = $nextDow - $dow;
838                                        }
839                                        else if ($dow > $nextDow)
840                                        {
841                                            $firstDowOffset = (7 - $dow) + $nextDow;
842                                        }
843                                    }
844                                    else
845                                    {
846                                        if ($dow < $nextDow)
847                                        {
848                                            $dowOffsets[] = $nextDow - $dow;
849                                        }
850                                        else if ($dow > $nextDow)
851                                        {
852                                            $dowOffsets[] = (7 - $dow) + $nextDow;
853                                        }
854                                        else
855                                        {
856                                            $dowOffsets[] = 7;
857                                        }
858
859                                    }
860
861                                    $dow = $nextDow;
862                                    if (!isset($firstDow))
863                                    {
864                                        $firstDow = $dow;
865                                    }
866
867                                }
868
869            //                    $nextDow = $this->getNextDow($nextDow);
870            //                    $mask = $this->wdays[$nextDow];
871
872                            }
873
874                            if ($firstDayMismatch)
875                            {
876                                if ($dow < $firstDow)
877                                {
878                                    $dowOffsets[] = $firstDow - $dow;
879                                }
880                                else if ($dow > $firstDow)
881                                {
882                                    $dowOffsets[] = (7 - $dow) + $firstDow;
883                                }
884                            }
885
886                            // Gera os eventos
887                            $starttime = $this->maketime($event['start']);
888                            $endtime = $this->maketime($event['end']);
889                            $offset = 86400;
890
891                            $new_event = Array();
892                            $new_event['owner'] = $owner;
893                            $new_event['participants'] = $participants;
894                            $new_event['start'] = $starttime;
895                            $new_event['end'] = $endtime;
896                            $return[] = $new_event;
897
898                            if ($firstDayMismatch && $firstDowOffset != 0)
899                            {
900                                $multi = $firstDowOffset;
901
902                                $new_event = Array();
903                                $new_event['owner'] = $owner;
904                                $new_event['participants'] = $participants;
905                                $new_event['start'] = $starttime += $offset*$multi;
906                                $new_event['end'] = $endtime += $offset*$multi;
907                                $return[] = $new_event;
908                            }
909
910                            for ($i = 0, $multi = $dowOffsets[$i],
911                                $starttime += $offset*$multi,
912                                $endtime += $offset*$multi;
913                                $starttime <= $enddate;
914                                ++$i,
915                                $i = ($i < count($dowOffsets))?$i:0,
916                                $multi = $dowOffsets[$i],
917                                $starttime += $offset*$multi,
918                                $endtime += $offset*$multi)
919                            {
920                                //error_log('loop infinito?');
921                                $new_event = Array();
922                                $new_event['owner'] = $owner;
923                                $new_event['participants'] = $participants;
924                                $new_event['start'] = $starttime; // + $offset*$multi;
925                                $new_event['end'] = $endtime; // + $offset*$multi;
926                                $return[] = $new_event;
927                            }
928
929
930                            break;
931                        case MCAL_RECUR_MONTHLY_WDAY:
932                            // Not working!!!
933                            break;
934                        case MCAL_RECUR_MONTHLY_MDAY:
935                        case MCAL_RECUR_YEARLY:
936
937                            for ($key = ($event['recur_type'] == MCAL_RECUR_YEARLY)?'year':'month',
938                                $starttime = $event['start'], $endtime = $event['end'];
939                                $this->maketime($starttime) <= $enddate;
940                                $starttime['year'] = ($key == 'month' && $starttime['month'] == 12)?$starttime['year']+1:$starttime['year'],
941                                $endtime['year'] = ($key == 'month' && $endtime['month'] == 12)?$endtime['year']+1:$endtime['year'],
942                                $starttime[$key] = ($key == 'year')?$starttime[$key]+1:($key == 'month' && $starttime[$key] < 12)?$starttime[$key]+1:1,
943                                $endtime[$key] = ($key == 'year')?$endtime[$key]+1:($key == 'month' && $endtime[$key] < 12)?$endtime[$key]+1:1)
944                            {
945                                $new_event = Array();
946                                $new_event['owner'] = $owner;
947                                $new_event['participants'] = $participants;
948                                $new_event['start'] = $this->maketime($starttime);
949                                $new_event['end'] = $this->maketime($endtime);
950                                $return[] = $new_event;
951                            }
952
953                            break;
954            //            default:
955            //                return Array();
956
957                    }
958
959                    return $return;
960                }
961
962                function update($params='')
963                {
964                        $prefix = ( $params['from_mobile'] ? "mobile.ui_mobile" : "calendar.ui" ) . "calendar";
965                       
966                        $ui_return = "$prefix.edit";
967                        $ui_index = "$prefix.index";
968                       
969                        if(!is_object($GLOBALS['phpgw']->datetime))
970                        {
971                                $GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
972                        }
973                        $l_cal = (@isset($params['cal']) && $params['cal']?$params['cal']:$_POST['cal']);
974                        $l_participants = (@$params['participants']?$params['participants']:$_POST['participants']);
975
976                        require_once(dirname(__FILE__).'/class.ex_participants.inc.php');
977                        $this->ex_participants = new exParticipants();
978                        $this->ex_participants->setParticipantsByString(@$params['ex_participants']?$params['ex_participants']:$_POST['ex_participants']);
979
980                        if(@$params['h_exParticipants']?$params['h_exParticipants']:$_POST['h_exParticipants'])
981                             $this->ex_participants->updateAttribBySerializable(@$params['h_exParticipants']?$params['h_exParticipants']:$_POST['h_exParticipants']);
982
983                        $l_categories = (@$params['categories']?$params['categories']:$_POST['categories']);
984                        $l_start = (@isset($params['start']) && $params['start']?$params['start']:$_POST['start']);
985                        $l_end = (@isset($params['end']) && $params['end']?$params['end']:$_POST['end']);
986                        $l_recur_enddate = (@isset($params['recur_enddate']) && $params['recur_enddate']?$params['recur_enddate']:$_POST['recur_enddate']);
987
988                       
989                        $send_to_ui = True;
990                        //if ((!is_array($l_start) || !is_array($l_end)) && !isset($_GET['readsess']))  // xmlrpc call
991                        if ($this->xmlrpc)      // xmlrpc call
992                        {
993                                $send_to_ui = False;
994
995                                $l_cal = $params;       // no extra array
996
997                                foreach(array('start','end','recur_enddate') as $name)
998                                {
999                                        $var = 'l_'.$name;
1000                                        $$var = $GLOBALS['server']->iso86012date($params[$name]);
1001                                        unset($l_cal[$name]);
1002                                }
1003                                if (!is_array($l_participants) || !count($l_participants))
1004                                {
1005                                        $l_participants = array($GLOBALS['phpgw_info']['user']['account_id'].'A');
1006                                }
1007                                else
1008                                {
1009                                        $l_participants = array();
1010                                        foreach($params['participants'] as $user => $data)
1011                                        {
1012                                                $l_participants[] = $user.$data['status'];
1013                                        }
1014                                }
1015
1016
1017                                if (!is_object($GLOBALS['phpgw']->categories))
1018                                {
1019                                        $GLOBALS['phpgw']->categories = CreateObject('phpgwapi.categories');
1020                                }
1021                                $l_categories = $GLOBALS['server']->xmlrpc2cats($params['category']);
1022                                unset($l_cal['category']);
1023
1024                                // using access={public|private} in all modules via xmlrpc
1025                                $l_cal['public'] = $params['access'] != 'private';
1026                                unset($l_cal['access']);
1027/*
1028                                $fp = fopen('/tmp/xmlrpc.log','a+');
1029                                ob_start();
1030                                echo "\nbocalendar::update("; print_r($params); echo ")\n";
1031                                //echo "\nl_start="; print_r($l_start);
1032                                //echo "\nl_end="; print_r($l_end);
1033                                fwrite($fp,ob_get_contents());
1034                                ob_end_clean();
1035                                fclose($fp);
1036*/
1037                        }
1038                        print_debug('ID',$l_cal['id']);
1039
1040                        // don't wrap to the next day for no time
1041                        if ($l_end['hour'] == 24 && $l_end['min'] == 0)
1042                        {
1043                                $l_end['hour'] = 23;
1044                                $l_end['min'] = 59;
1045                        }
1046
1047                        if(isset($_GET['readsess']))
1048                        {
1049                                $event = $this->restore_from_appsession();
1050                                $event['title'] = stripslashes($event['title']);
1051                                $event['description'] = stripslashes($event['description']);
1052                                $event['ex_participants'] = stripslashes($event['ex_participants']);
1053                                $datetime_check = $this->validate_update($event);
1054                                if($datetime_check)
1055                                {
1056                                        ExecMethod($ui_return,
1057                                                Array(
1058                                                        'cd'            => $datetime_check,
1059                                                        'readsess'      => 1
1060                                                )
1061                                        );
1062                                        if(!$params['from_mobile'])
1063                                                $GLOBALS['phpgw']->common->phpgw_exit(True);
1064                                        else
1065                                                return;
1066                                }
1067                                //$overlapping_events = False;
1068                        }
1069                        else
1070                        {
1071                                if((!$l_cal['id'] && !$this->check_perms(PHPGW_ACL_ADD)) ||
1072                                   ($l_cal['id'] && !$this->check_perms(PHPGW_ACL_EDIT,$l_cal['id'])))
1073                                {
1074                                        if ($this->xmlrpc)
1075                                        {
1076                                                $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
1077                                        }
1078                                        if (!$send_to_ui)
1079                                        {
1080                                                return array(($l_cal['id']?1:2) => 'permission denied');
1081                                        }
1082                                        ExecMethod($ui_index);
1083                                        if(!$params['from_mobile'])
1084                                                $GLOBALS['phpgw']->common->phpgw_exit();
1085                                        else
1086                                                return;
1087                                }
1088
1089                                print_debug('Prior to fix_update_time()');
1090                                $this->fix_update_time($l_start);
1091                                $this->fix_update_time($l_end);
1092                                if(!isset($l_cal['ex_participants']))
1093                                {
1094                                        $l_cal['ex_participants'] = $this->ex_participants->getParticipantsSerializable();
1095                                }
1096
1097                                if(!isset($l_categories))
1098                                {
1099                                        $l_categories = 0;
1100                                }
1101
1102                                $is_public = ($l_cal['type'] != 'private' && $l_cal['type'] != 'privateHiddenFields');
1103                                $this->so->event_init();
1104
1105                                if($l_cal['uid'])
1106                                $this->add_attribute('uid',$l_cal['uid']);
1107                                else
1108                                $this->add_attribute('uid',time().'@Expresso');
1109                               
1110
1111                                $this->add_attribute('type',$l_cal['type']);
1112                                if($l_cal['ex_participants']) {
1113                                        $this->add_attribute('ex_participants',$l_cal['ex_participants']);
1114                                }
1115                                if(count($l_categories) >= 2)
1116                                {
1117                                        $this->so->set_category(implode(',',$l_categories));
1118                                }
1119                                else
1120                                {
1121                                        $this->so->set_category(strval($l_categories[0]));
1122                                }
1123                                $this->so->set_title($l_cal['title']);
1124                                $this->so->set_description($l_cal['description']);
1125                                $this->so->set_ex_participants($l_cal['ex_participants']);
1126                                $this->so->set_start($l_start['year'],$l_start['month'],$l_start['mday'],$l_start['hour'],$l_start['min'],0);
1127                                $this->so->set_end($l_end['year'],$l_end['month'],$l_end['mday'],$l_end['hour'],$l_end['min'],0);
1128                                $this->so->set_class($is_public);
1129                                $this->so->add_attribute('reference',(@isset($l_cal['reference']) && $l_cal['reference']?$l_cal['reference']:0));
1130                                $this->so->add_attribute('location',(@isset($l_cal['location']) && $l_cal['location']?$l_cal['location']:''));
1131                                if($l_cal['id'])
1132                                {
1133                                        $this->so->add_attribute('id',$l_cal['id']);
1134                                }
1135
1136                                if($l_cal['rpt_use_end'] != 'y')
1137                                {
1138                                        $l_recur_enddate['year'] = 0;
1139                                        $l_recur_enddate['month'] = 0;
1140                                        $l_recur_enddate['mday'] = 0;
1141                                }
1142                                elseif (isset($l_recur_enddate['str']))
1143                                {
1144                                        $l_recur_enddate = $this->jscal->input2date($l_recur_enddate['str'],False,'mday');
1145                                }
1146
1147                                switch((int)$l_cal['recur_type'])
1148                                {
1149                                        case MCAL_RECUR_NONE:
1150                                                $this->so->set_recur_none();
1151
1152                                                $this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
1153
1154                                                break;
1155                                        case MCAL_RECUR_DAILY:
1156                                                $this->so->set_recur_daily((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
1157
1158                                                $this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
1159
1160                                                $tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
1161                                                $init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
1162
1163                                                if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
1164                                                {
1165                                                       
1166                                                        $tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
1167                                                        $end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
1168
1169                                                }else { // se nao existe data final da repeticao (agendamento infinito):
1170
1171                                                        $end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
1172                                                }
1173                                                break;
1174                                        case MCAL_RECUR_WEEKLY:
1175
1176                                                $this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
1177
1178                                                $tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
1179                                                $init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
1180
1181                                                if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
1182                                                {
1183
1184                                                        $tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
1185                                                        $end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
1186
1187                                                }else { // se nao existe data final da repeticao (agendamento infinito):
1188
1189                                                        $end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
1190                                                }
1191
1192                                                foreach(array('rpt_sun','rpt_mon','rpt_tue','rpt_wed','rpt_thu','rpt_fri','rpt_sat') as $rpt_day)
1193                                                {
1194                                                        $l_cal['recur_data'] += (int)$l_cal[$rpt_day];
1195                                                }
1196                                                if (is_array($l_cal['rpt_day']))
1197                                                {
1198                                                        foreach ($l_cal['rpt_day'] as $mask)
1199                                                        {
1200                                                                $l_cal['recur_data'] |= (int)$mask;
1201                                                                $rpt_wdays = $l_cal['recur_data']; // recebe os dias da semana (somatorio) para repetir o alarme;
1202                                                        }
1203                                                }
1204                                                $this->so->set_recur_weekly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval'],$l_cal['recur_data']);
1205                                                break;
1206                                        case MCAL_RECUR_MONTHLY_MDAY:
1207                                                $this->so->set_recur_monthly_mday((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
1208
1209                                                $this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
1210
1211                                                $tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
1212                                                $init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
1213
1214                                                if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
1215                                                {
1216
1217                                                        $tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
1218                                                        $end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
1219
1220                                                }else { // se nao existe data final da repeticao (agendamento infinito):
1221
1222                                                        $end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
1223                                                }
1224                                                break;
1225                                        case MCAL_RECUR_MONTHLY_WDAY:
1226                                                $this->so->set_recur_monthly_wday((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
1227                                                break;
1228                                        case MCAL_RECUR_YEARLY:
1229                                                $this->so->set_recur_yearly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
1230
1231                                                $this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
1232
1233                                                $tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
1234                                                $init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
1235
1236                                                if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
1237                                                {
1238
1239                                                        $tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
1240                                                        $end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
1241
1242                                                }else { // se nao existe data final da repeticao (agendamento infinito):
1243
1244                                                        $end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
1245                                                }
1246                                                break;
1247                                }
1248
1249                                if($l_participants)
1250                                {
1251                                        $parts = $l_participants;
1252                                        $minparts = min($l_participants);
1253                                        $part = Array();
1254                    $parts_count = count($parts);
1255                                        for($i=0;$i<$parts_count;++$i)
1256                                        {
1257                                                if (($accept_type = substr($parts[$i],-1,1)) == '0' || (int)$accept_type > 0)
1258                                                {
1259                                                        $accept_type = 'U';
1260                                                }
1261                                                $acct_type = $GLOBALS['phpgw']->accounts->get_type((int)$parts[$i]);
1262                                                if($acct_type == 'u' || $acct_type == 's')
1263                                                {
1264                                                        $part[(int)$parts[$i]] = $accept_type;
1265                                                }
1266                                                elseif($acct_type == 'g')
1267                                                {
1268                                                        $part[(int)$parts[$i]] = $accept_type;
1269                                                        $groups[] = $parts[$i];
1270                                                        /* This pulls ALL users of a group and makes them as participants to the event */
1271                                                        /* I would like to turn this back into a group thing. */
1272                                                        $acct = CreateObject('phpgwapi.accounts',(int)$parts[$i]);
1273                                                        $members = $acct->member((int)$parts[$i]);
1274                                                        unset($acct);
1275                                                        if($members == False)
1276                                                        {
1277                                                                continue;
1278                                                        }
1279                                                        while($member = each($members))
1280                                                        {
1281                                                                $part[$member[1]['account_id']] = $accept_type;
1282                                                        }
1283                                                }
1284                                        }
1285                                }
1286                                else
1287                                {
1288                                        $part = False;
1289                                }
1290
1291                                if($part)
1292                                {
1293                                        @reset($part);
1294                                        while(list($key,$accept_type) = each($part))
1295                                        {
1296                                                $this->so->add_attribute('participants',$accept_type,(int)$key);
1297                                        }
1298                                }
1299
1300                                if($groups)
1301                                {
1302                                        @reset($groups);
1303                                        $this->so->add_attribute('groups',(int)$group_id);
1304                                }
1305
1306                                $event = $this->get_cached_event();
1307                                if(!is_int($minparts))
1308                                {
1309                                        $minparts = $this->owner;
1310                                }
1311                                if(!@isset($event['participants'][$l_cal['owner']]))
1312                                {
1313                                        $this->so->add_attribute('owner',$minparts);
1314                                }
1315                                else
1316                                {
1317                                        $this->so->add_attribute('owner',$l_cal['owner']);
1318                                }
1319                                $this->so->add_attribute('priority',$l_cal['priority']);
1320
1321                                foreach($l_cal as $name => $value)
1322                                {
1323                                        if ($name[0] == '#')    // Custom field
1324                                        {
1325                                                $this->so->add_attribute($name,stripslashes($value));
1326                                        }
1327                                }
1328                                if (isset($_POST['preserved']) && is_array($preserved = unserialize(stripslashes($_POST['preserved']))))
1329                                {
1330                                        foreach($preserved as $name => $value)
1331                                        {
1332                                                switch($name)
1333                                                {
1334                                                        case 'owner':
1335                                                                $this->so->add_attribute('participants',$value,$l_cal['owner']);
1336                                                                break;
1337                                                        default:
1338                                                                $this->so->add_attribute($name,str_replace(array('&amp;','&quot;','&lt;','&gt;'),array('&','"','<','>'),$value));
1339                                                }
1340                                        }
1341                                }
1342                                $event = $this->get_cached_event();
1343
1344                                if ($l_cal['alarmdays'] > 0 || $l_cal['alarmhours'] > 0 ||$l_cal['alarmminutes'] > 0)
1345                                {
1346                                        $offset = ($l_cal['alarmdays'] * 24 * 3600) +
1347                                                ($l_cal['alarmhours'] * 3600) + ($l_cal['alarmminutes'] * 60);
1348
1349                                        $time = $this->maketime($event['start']) - $offset;
1350
1351                                        $event['alarm'][] = Array(
1352                                                'time'    => $time,
1353                                                'offset'  => $offset,
1354                                                'owner'   => $this->owner,
1355                                                'enabled' => 1,
1356                                                'repeat'  => $this->repetido, // para repetir alarme;
1357                                                'init_rept' => $init_rept, // inicio repeticao;
1358                                                'end_rept' => $end_rept, // fim repeticao;
1359                                                'rpt_wdays' => $rpt_wdays // dias repeticao da semana;
1360                                        );
1361                                }
1362
1363                                $this->store_to_appsession($event);
1364                                $datetime_check = $this->validate_update($event);
1365                                print_debug('bo->validated_update() returnval',$datetime_check);
1366                                if($datetime_check)
1367                                {
1368                                        if (!$send_to_ui)
1369                                        {
1370                                                return array($datetime_check => 'invalid input data');
1371                                        }
1372                                        ExecMethod($ui_return,
1373                                                Array(
1374                                                        'cd'            => $datetime_check,
1375                                                        'readsess'      => 1
1376                                                )
1377                                        );
1378                                        if(!$params['from_mobile'])
1379                                                $GLOBALS['phpgw']->common->phpgw_exit(True);
1380                                        else
1381                                                return;
1382                                }
1383
1384                            $overlapping_events = $this->event_overlap( $event, $send_to_ui, $prefix );
1385
1386                            if( $overlapping_events )
1387                                return( $overlapping_events );
1388                        }
1389
1390                                $event['ex_participants'] = $this->ex_participants->getParticipantsSerializable();
1391                       
1392                        if($event['owner'] != $GLOBALS['phpgw_info']['user']['account_id']) $userSend = $event['owner'];
1393                        else $userSend = false;
1394       
1395                        if(!$event['id'])
1396                        {
1397                                /** Whenever a recurrent event is edit in a way that a new 
1398                                 * exception is created, an exception must be added to
1399                                 * the old event. This is necessary to keep consistency
1400                                 * with synchornization solutions in accordancy to
1401                                 * the iCalendar RFC.
1402                                 */
1403                                $old_event = $this->so->read_entry($_POST['cal']['reference']);
1404
1405                                $date = $_POST['cal']['date'];
1406                                $year  = substr($date,0,4);
1407                                $month = substr($date,4,2);
1408                                $day   = substr($date,6,2);
1409
1410                                $exception_time = mktime($old_event['start']['hour'],$old_event['start']['min'],0,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
1411                                $old_event['recur_exception'][] = (int)$exception_time;
1412                                $this->so->add_entry($old_event,false);
1413                           
1414                           
1415                                $this->so->add_entry($event,false);
1416                                print_debug('New Event ID',$event['id']);
1417                                $send_type = MSG_ADDED;
1418                        }
1419                        else
1420                        {
1421                                print_debug('Updating Event ID',$event['id']);
1422                                $new_event = $event;
1423                                $old_event = $this->read_entry($event['id']);
1424                                // if old event has alarm and the start-time changed => update them
1425                                //echo "<p>checking ".count($old_event['alarm'])." alarms of event #$event[id] start moved from ".print_r($old_event['start'],True)." to ".print_r($event['start'],True)."</p>\n";
1426                                if ($old_event['alarm'] &&
1427                                        $this->maketime($old_event['start']) != $this->maketime($event['start']))
1428                                {
1429                                        $this->so->delete_alarms($old_event['id']);
1430                                        foreach($old_event['alarm'] as $id => $alarm)
1431                                        {
1432                                                $alarm['time'] = $this->maketime($event['start']) - $alarm['offset'];
1433                                                $event['alarm'][] = $alarm;
1434                                        }
1435                                        //echo "updated alarms<pre>".print_r($event['alarm'],True)."</pre>\n";
1436                                }
1437                                $this->so->cal->event = $event;
1438                                $this->so->add_entry($event,false);
1439                                $this->prepare_recipients($new_event,$old_event,$userSend);
1440                                $send_type = MSG_MODIFIED;
1441                        }
1442                     
1443                        //Retira da lista usuarios ja notificados
1444                        $to_notify = $event['participants'];
1445                        foreach ($this->alreadyNotifieds as $key => $value)
1446                            if(array_key_exists($value,$to_notify))
1447                                unset ($to_notify[$value]);
1448                        //------------------------------------------------//
1449                           
1450                        if(count($to_notify) > 0 && $userSend !== -2)   
1451                            $this->send_update( $send_type,$to_notify,'',$this->get_cached_event(),$userSend);
1452
1453                        $date = sprintf("%04d%02d%02d",$event['start']['year'],$event['start']['month'],$event['start']['mday']);
1454                        if($send_to_ui)
1455                        {
1456                                $this->read_sessiondata();
1457                                if ($this->return_to)
1458                                {
1459                                        $GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.$this->return_to);
1460                                        $GLOBALS['phpgw']->common->phpgw_exit();
1461                                }
1462                                Execmethod($ui_index);
1463                        }
1464                        else
1465                        {
1466                                return (int)$event['id'];
1467                        }
1468
1469                        return True;
1470                }
1471
1472                function event_overlap( $event, $send_to_ui = false, $prefix = "calendar.uicalendar" ,$user = false)
1473                {
1474                    $event_ids = array();
1475
1476                                if($event['id'])
1477                                {
1478                                        $event_ids[] = $event['id'];
1479                                }
1480                                if($event['reference'])
1481                                {
1482                                        $event_ids[] = $event['reference'];
1483                                }
1484
1485                    if (isset($this->repetido) and $this->repetido > 0)
1486                    {
1487                                    $events = $this->expand_repetition($event);
1488                                    $overlapping_events = False;
1489                                    foreach($events as $evt){
1490                                        $overlap = $this->overlap(
1491                                            $evt['start'],
1492                                            $evt['end'],
1493                                            $evt['participants'],
1494                                            $evt['owner'],
1495                                            $event_ids);
1496                                        if ($overlap)
1497                                        {
1498                                            if (!$overlapping_events)
1499                                            {
1500                                                $overlapping_events = Array();
1501                                            }
1502                                            array_push($overlapping_events, $overlap);
1503                                        }
1504                                    }
1505                                }
1506                    else
1507                    {
1508                                    $overlapping_events = $this->overlap(
1509                                        $this->maketime($event['start']),
1510                                        $this->maketime($event['end']),
1511                                        $event['participants'],
1512                                        $event['owner'],
1513                                        $event_ids
1514                                    );
1515                                }
1516                                     
1517                        if($overlapping_events)
1518                        {
1519                            $this->store_to_appsession( $event );
1520                                if($send_to_ui)
1521                                {
1522                                        unset($GLOBALS['phpgw_info']['flags']['noheader']);
1523                                        unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
1524                                    ExecMethod("$prefix.overlap",
1525                                                Array(
1526                                                        'o_events'      => $overlapping_events,
1527                                                    'this_event'        => $event,
1528                                                    'this_account' => $user
1529                                                )
1530                                        );
1531
1532                                    if( $prefix === "calendar.uicalendar" )
1533                                                $GLOBALS['phpgw']->common->phpgw_exit(True);
1534                                }
1535
1536                            return( $overlapping_events );
1537                        }
1538
1539                    return( false );
1540                }
1541
1542                /* Private functions */
1543                function read_holidays($year=0)
1544                {
1545                        if(!$year)
1546                        {
1547                                $year = $this->year;
1548                        }
1549                        $holiday = CreateObject('calendar.boholiday');
1550                        $holiday->prepare_read_holidays($year,$this->owner);
1551                        $this->cached_holidays = $holiday->read_holiday();
1552                        unset($holiday);
1553                }
1554
1555                function user_is_a_member($event,$user)
1556                {
1557                        @reset($event['participants']);
1558                        $uim = False;
1559                        $security_equals = $GLOBALS['phpgw']->accounts->membership($user);
1560                        while(!$uim && $event['participants'] && $security_equals && list($participant,$status) = each($event['participants']))
1561                        {
1562                                if($GLOBALS['phpgw']->accounts->get_type($participant) == 'g')
1563                                {
1564                                        @reset($security_equals);
1565                                        while(list($key,$group_info) = each($security_equals))
1566                                        {
1567                                                if($group_info['account_id'] == $participant)
1568                                                {
1569                                                        return True;
1570                                                        $uim = True;
1571                                                }
1572                                        }
1573                                }
1574                        }
1575                        return $uim;
1576                }
1577
1578                function maketime($time)
1579                {
1580                        return mktime(intval($time['hour']),intval($time['min']),intval($time['sec']),intval($time['month']),intval($time['mday']),intval($time['year']));
1581                }
1582
1583                /*!
1584                @function time2array
1585                @abstract returns a date-array suitable for the start- or endtime of an event from a timestamp
1586                @syntax time2array($time,$alarm=0)
1587                @param $time the timestamp for the values of the array
1588                @param $alarm (optional) alarm field of the array, defaults to 0
1589                @author ralfbecker
1590                */
1591                function time2array($time,$alarm = 0)
1592                {
1593                        return array(
1594                                'year'  => (int)(date('Y',$time)),
1595                                'month' => (int)(date('m',$time)),
1596                                'mday'  => (int)(date('d',$time)),
1597                                'hour'  => (int)(date('H',$time)),
1598                                'min'   => (int)(date('i',$time)),
1599                                'sec'   => (int)(date('s',$time)),
1600                                'alarm' => (int)($alarm)
1601                        );
1602                }
1603
1604                /*!
1605                @function set_recur_date
1606                @abstract set the start- and enddates of a recuring event for a recur-date
1607                @syntax set_recur_date(&$event,$date)
1608                @param $event the event which fields to set (has to be the original event for start-/end-times)
1609                @param $date  the recuring date in form 'Ymd', eg. 20030226
1610                @author ralfbecker
1611                */
1612                function set_recur_date(&$event,$date)
1613                {
1614                        $org_start = $this->maketime($event['start']);
1615                        $org_end   = $this->maketime($event['end']);
1616                        $start = mktime($event['start']['hour'],$event['start']['min'],0,substr($date,4,2),substr($date,6,2),substr($date,0,4));
1617                        $end   = $org_end + $start - $org_start;
1618                        $event['start'] = $this->time2array($start);
1619                        $event['end']   = $this->time2array($end);
1620                }
1621
1622                function fix_update_time(&$time_param)
1623                {
1624                        if (isset($time_param['str']))
1625                        {
1626                                if (!is_object($this->jscal))
1627                                {
1628                                        $this->jscal = CreateObject('phpgwapi.jscalendar');
1629                                }
1630                                $time_param += $this->jscal->input2date($time_param['str'],False,'mday');
1631                                unset($time_param['str']);
1632                        }
1633                        if ($this->prefs['common']['timeformat'] == '12')
1634                        {
1635                                if ($time_param['ampm'] == 'pm')
1636                                {
1637                                        if ($time_param['hour'] <> 12)
1638                                        {
1639                                                $time_param['hour'] += 12;
1640                                        }
1641                                }
1642                                elseif ($time_param['ampm'] == 'am')
1643                                {
1644                                        if ($time_param['hour'] == 12)
1645                                        {
1646                                                $time_param['hour'] -= 12;
1647                                        }
1648                                }
1649
1650                                if($time_param['hour'] > 24)
1651                                {
1652                                        $time_param['hour'] -= 12;
1653                                }
1654                        }
1655                }
1656
1657                function validate_update($event)
1658                {
1659                        $error = 0;
1660                        // do a little form verifying
1661                        if (!count($event['participants']))
1662                        {
1663                                $error = 43;
1664                        }
1665                        elseif ($event['title'] == '')
1666                        {
1667                                $error = 40;
1668                        }
1669                        elseif (($GLOBALS['phpgw']->datetime->time_valid($event['start']['hour'],$event['start']['min'],0) == False) || ($GLOBALS['phpgw']->datetime->time_valid($event['end']['hour'],$event['end']['min'],0) == False))
1670                        {
1671                                $error = 41;
1672                        }
1673                        elseif (($GLOBALS['phpgw']->datetime->date_valid($event['start']['year'],$event['start']['month'],$event['start']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_valid($event['end']['year'],$event['end']['month'],$event['end']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 1))
1674                        {
1675                                $error = 42;
1676                        }
1677                        elseif ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 0)
1678                        {
1679                                if ($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 1)
1680                                {
1681                                        $error = 42;
1682                                }
1683                        }
1684                       
1685                        return $error;
1686                }
1687
1688                /*!
1689                @function participants_not_rejected($participants,$event)
1690                @abstract checks if any of the $particpants participates in $event and has not rejected it
1691                */
1692                function participants_not_rejected($participants,$event)
1693                {
1694                        //echo "participants_not_rejected()<br>participants =<pre>"; print_r($participants); echo "</pre><br>event[participants]=<pre>"; print_r($event['participants']); echo "</pre>\n";
1695                        foreach($participants as $uid => $status)
1696                        {
1697                                //echo "testing event[participants][uid=$uid] = '".$event['participants'][$uid]."'<br>\n";
1698                                if (isset($event['participants'][$uid]) && $event['participants'][$uid] != 'R' &&
1699                                        $status != 'R')
1700                                {
1701                                        return True;    // found not rejected participant in event
1702                                }
1703                        }
1704                        return False;
1705                }
1706               
1707                function overlap($starttime,$endtime,$participants,$owner=0,$id=0,$restore_cache=False)
1708                {
1709//                      $retval = Array();
1710//                      $ok = False;
1711
1712/* This needs some attention.. by commenting this chunk of code it will fix bug #444265 */
1713
1714                        if($restore_cache)
1715                        {
1716                                $temp_cache_events = $this->cached_events;
1717                        }
1718
1719//                      $temp_start = (int)$GLOBALS['phpgw']->common->show_date($starttime,'Ymd');
1720//                      $temp_start_time = (int)($GLOBALS['phpgw']->common->show_date($starttime,'Hi');
1721//                      $temp_end = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Ymd');
1722//                      $temp_end_time = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Hi');
1723                        $temp_start = (int)(date('Ymd',$starttime));
1724                        $temp_start_time = (int)(date('Hi',$starttime));
1725                        $temp_end = (int)(date('Ymd',$endtime));
1726                        $temp_end_time = (int)(date('Hi',$endtime));
1727                        if($this->debug)
1728                        {
1729                                echo '<!-- Temp_Start: '.$temp_start.' -->'."\n";
1730                                echo '<!-- Temp_End: '.$temp_end.' -->'."\n";
1731                        }
1732
1733                        $users = Array();
1734                        if(count($participants))
1735                        {
1736                                while(list($user,$status) = each($participants))
1737                                {
1738                                        $users[] = $user;
1739                                }
1740                        }
1741                        else
1742                        {
1743                                $users[] = $this->owner;
1744                        }
1745
1746                        $possible_conflicts = $this->store_to_cache(
1747                                Array(
1748                                        'smonth'        => substr(strval($temp_start),4,2),
1749                                        'sday'  => substr(strval($temp_start),6,2),
1750                                        'syear' => substr(strval($temp_start),0,4),
1751                                        'emonth'        => substr(strval($temp_end),4,2),
1752                                        'eday'  => substr(strval($temp_end),6,2),
1753                                        'eyear' => substr(strval($temp_end),0,4),
1754                                        'owner' => $users
1755                                )
1756                        );
1757
1758                        if($this->debug)
1759                        {
1760                                echo '<!-- Possible Conflicts ('.($temp_start - 1).'): '.count($possible_conflicts[$temp_start - 1]).' -->'."\n";
1761                                echo '<!-- Possible Conflicts ('.$temp_start.'): '.count($possible_conflicts[$temp_start]).' '.count($id).' -->'."\n";
1762                        }
1763
1764                        if($possible_conflicts[$temp_start] || $possible_conflicts[$temp_end])
1765                        {
1766                                if($temp_start == $temp_end)
1767                                {
1768                                        if($this->debug)
1769                                        {
1770                                                echo '<!-- Temp_Start == Temp_End -->'."\n";
1771                                        }
1772                                        @reset($possible_conflicts[$temp_start]);
1773                                        while(list($key,$event) = each($possible_conflicts[$temp_start]))
1774                                        {
1775                                                $found = False;
1776                                                if($id)
1777                                                {
1778                                                        @reset($id);
1779                                                        while(list($key,$event_id) = each($id))
1780                                                        {
1781                                                                if($this->debug)
1782                                                                {
1783                                                                        echo '<!-- $id['.$key.'] = '.$id[$key].' = '.$event_id.' -->'."\n";
1784                                                                        echo '<!-- '.$event['id'].' == '.$event_id.' -->'."\n";
1785                                                                }
1786                                                                if($event['id'] == $event_id)
1787                                                                {
1788                                                                        $found = True;
1789                                                                }
1790                                                        }
1791                                                }
1792                                                if($this->debug)
1793                                                {
1794                                                        echo '<!-- Item found: '.$found.' -->'."<br>\n";
1795                                                }
1796                                                if(!$found)
1797                                                {
1798                                                        if($this->debug)
1799                                                        {
1800                                                                echo '<!-- Checking event id #'.$event['id'];
1801                                                        }
1802                                                        $temp_event_start = sprintf("%d%02d",$event['start']['hour'],$event['start']['min']);
1803                                                        $temp_event_end = sprintf("%d%02d",$event['end']['hour'],$event['end']['min']);
1804//                                                      if((($temp_start_time <= $temp_event_start) && ($temp_end_time >= $temp_event_start) && ($temp_end_time <= $temp_event_end)) ||
1805                                                        if(($temp_start_time <= $temp_event_start &&
1806                                                                $temp_end_time > $temp_event_start &&
1807                                                                $temp_end_time <= $temp_event_end ||
1808                                                                $temp_start_time >= $temp_event_start &&
1809                                                                $temp_start_time < $temp_event_end &&
1810                                                                $temp_end_time >= $temp_event_end ||
1811                                                                $temp_start_time <= $temp_event_start &&
1812                                                                $temp_end_time >= $temp_event_end ||
1813                                                                $temp_start_time >= $temp_event_start &&
1814                                                                $temp_end_time <= $temp_event_end) &&
1815                                                                $this->participants_not_rejected($participants,$event))
1816                                                        {
1817                                                                if($this->debug)
1818                                                                {
1819                                                                        echo ' Conflicts';
1820                                                                }
1821                                                                $retval[] = $event['id'];
1822                                                        }
1823                                                        if($this->debug)
1824                                                        {
1825                                                                echo ' -->'."\n";
1826                                                        }
1827                                                }
1828                                        }
1829                                }
1830                        }
1831                        else
1832                        {
1833                                $retval = False;
1834                        }
1835
1836                        if($restore_cache)
1837                        {
1838                                $this->cached_events = $temp_cache_events;
1839                        }
1840
1841                        return $retval;
1842                }
1843
1844                /*!
1845                @function check_perms( )
1846                @syntax check_perms($needed,$event=0,$other=0)
1847                @abstract Checks if the current user has the necessary ACL rights
1848                @author ralfbecker
1849                @discussion The check is performed on an event or general on the cal of an other user
1850                @param $needed necessary ACL right: PHPGW_ACL_{READ|EDIT|DELETE}
1851                @param $event event as array or the event-id or 0 for general check
1852                @param $other uid to check (if event==0) or 0 to check against $this->owner
1853                @note Participating in an event is considered as haveing read-access on that event, \
1854                        even if you have no general read-grant from that user.
1855                */
1856                function check_perms($needed,$event=0,$other=0)
1857                {
1858                        $event_in = $event;
1859                       
1860                        if (is_int($event) && $event == 0)
1861                        {
1862                                $owner = $other > 0 ? $other : $this->owner;
1863                        }
1864                        else
1865                        {
1866                                if (!is_array($event))
1867                                {
1868                                        $event = $this->so->read_entry((int) $event);
1869                                }
1870                                if (!is_array($event))
1871                                {
1872                                        if ($this->xmlrpc)
1873                                        {
1874                                                $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
1875                                        }
1876                                        return False;
1877                                }
1878                                $owner = $event['owner'];
1879                                $private = $event['public'] == False || $event['public'] == 0;
1880                        }
1881                        $user = $GLOBALS['phpgw_info']['user']['account_id'];
1882                        $grants = $this->grants[$owner];
1883
1884                        if (is_array($event) && $needed == PHPGW_ACL_READ)
1885                        {
1886                                // Check if the $user is one of the participants or has a read-grant from one of them
1887                                //
1888                                foreach($event['participants'] as $uid => $accept)
1889                                {
1890                                        if ($this->grants[$uid] & PHPGW_ACL_READ || $uid == $user)
1891                                        {
1892                                                $grants |= PHPGW_ACL_READ;
1893                                                // if the $user is one of the participants read-grant private (restricted) too.
1894                                                if($uid == $user || ($this->grants[$uid] & PHPGW_ACL_PRIVATE)) {
1895                                                        $grants |= PHPGW_ACL_PRIVATE;
1896                                                }
1897                                                //break;
1898                                        }
1899                                }
1900                        }
1901
1902                        if ($GLOBALS['phpgw']->accounts->get_type($owner) == 'g' && $needed == PHPGW_ACL_ADD)
1903                        {
1904                                $access = False;        // a group can't be the owner of an event
1905                        }
1906                        else
1907                        {
1908                                $access = $user == $owner || $grants & $needed && (!$private || $grants & PHPGW_ACL_PRIVATE);
1909                        }
1910                        //echo "<p>".function_backtrace()." check_perms($needed,$event_id,$other) for user $user and needed_acl $needed: event='$event[title]': owner=$owner, private=$private, grants=$grants ==> access=$access</p>\n";
1911
1912                        return $access;
1913                }
1914
1915
1916                function display_status($user_status)
1917                {
1918                        if(@$this->prefs['calendar']['display_status'] && $user_status)
1919                        {
1920                                $user_status = substr($this->get_long_status($user_status),0,1);
1921
1922                                return ' ('.$user_status.')';
1923                        }
1924                        else
1925                        {
1926                                return '';
1927                        }
1928                }
1929
1930                function get_long_status($status_short)
1931                {
1932                        switch ($status_short)
1933                        {
1934                                case 'A':
1935                                        $status = lang('Accepted');
1936                                        break;
1937                                case 'R':
1938                                        $status = lang('Rejected');
1939                                        break;
1940                                case 'T':
1941                                        $status = lang('Tentative');
1942                                        break;
1943                                case 'U':
1944                                        $status = lang('No Response');
1945                                        break;
1946                        }
1947                        return $status;
1948                }
1949
1950                function is_private($event,$owner)
1951                {
1952                        if($owner == 0)
1953                        {
1954                                $owner = $this->owner;
1955                        }
1956                        if ($owner == $GLOBALS['phpgw_info']['user']['account_id'] || ($event['public']==1) || ($this->check_perms(PHPGW_ACL_PRIVATE,$event) && $event['public']==0) || $event['owner'] == $GLOBALS['phpgw_info']['user']['account_id'])
1957                        {
1958                                return False;
1959                        }
1960                        elseif($event['public'] == 0)
1961                        {
1962                                return True;
1963                        }
1964                        elseif($event['public'] == 2)
1965                        {
1966                                $is_private = True;
1967                                $groups = $GLOBALS['phpgw']->accounts->membership($owner);
1968                                while (list($key,$group) = each($groups))
1969                                {
1970                                        if (strpos(' '.implode(',',$event['groups']).' ',$group['account_id']))
1971                                        {
1972                                                return False;
1973                                        }
1974                                }
1975                        }
1976                        else
1977                        {
1978                                return False;
1979                        }
1980
1981                        return $is_private;
1982                }
1983
1984                function get_short_field($event,$is_private=True,$field='')
1985                {
1986                        if($is_private && $event['type'] == 'E')
1987                        {
1988                                return lang('Restrict');
1989                        }
1990                        else if($is_private && $event['type'] == 'P')
1991                        {
1992                                return lang('private');
1993                        }
1994
1995// cut off too long titles
1996                        elseif(strlen($event[$field]) > 19 && !$this->printer_friendly && $field=="title")
1997//                      elseif(strlen($event[$field]) > 19 && $this->printer_friendly)
1998                        {
1999// we dont use currently 160304
2000//                              return substr($event[$field], 0 , 19) . '&nbsp;...';
2001                                return $event[$field];
2002                        }
2003                        else
2004                        {
2005                                return $event[$field];
2006                        }
2007                }
2008
2009                function long_date($first,$last=0)
2010                {
2011                        if (!is_array($first))
2012                        {
2013                                $first = $this->time2array($raw = $first);
2014                                $first['raw'] = $raw;
2015                                $first['day'] = $first['mday'];
2016                        }
2017                        if ($last && !is_array($last))
2018                        {
2019                                $last = $this->time2array($raw = $last);
2020                                $last['raw'] = $raw;
2021                                $last['day'] = $last['mday'];
2022                        }
2023                        $datefmt = $this->prefs['common']['dateformat'];
2024
2025                        $month_before_day = strtolower($datefmt[0]) == 'm' ||
2026                                strtolower($datefmt[2]) == 'm' && $datefmt[4] == 'd';
2027
2028                        for ($i = 0; $i < 5; $i += 2)
2029                        {
2030                                switch($datefmt[$i])
2031                                {
2032                                        case 'd':
2033                                                $range .= $first['day'] . ($datefmt[1] == '.' ? '.' : '');
2034                                                if ($first['month'] != $last['month'] || $first['year'] != $last['year'])
2035                                                {
2036                                                        if (!$month_before_day)
2037                                                        {
2038                                                                $range .= ' '.lang(strftime('%B',$first['raw']));
2039                                                        }
2040                                                        if ($first['year'] != $last['year'] && $datefmt[0] != 'Y')
2041                                                        {
2042                                                                $range .= ($datefmt[0] != 'd' ? ', ' : ' ') . $first['year'];
2043                                                        }
2044                                                        if (!$last)
2045                                                        {
2046                                                                return $range;
2047                                                        }
2048                                                        $range .= ' - ';
2049
2050                                                        if ($first['year'] != $last['year'] && $datefmt[0] == 'Y')
2051                                                        {
2052                                                                $range .= $last['year'] . ', ';
2053                                                        }
2054
2055                                                        if ($month_before_day)
2056                                                        {
2057                                                                $range .= lang(strftime('%B',$last['raw']));
2058                                                        }
2059                                                }
2060                                                else
2061                                                {
2062                                                        $range .= ' - ';
2063                                                }
2064                                                $range .= ' ' . $last['day'] . ($datefmt[1] == '.' ? '.' : '');
2065                                                break;
2066                                        case 'm':
2067                                        case 'M':
2068                                                $range .= ' '.lang(strftime('%B',$month_before_day ? $first['raw'] : $last['raw'])) . ' ';
2069                                                break;
2070                                        case 'Y':
2071                                                $range .= ($datefmt[0] == 'm' ? ', ' : ' ') . ($datefmt[0] == 'Y' ? $first['year'].($datefmt[2] == 'd' ? ', ' : ' ') : $last['year'].' ');
2072                                                break;
2073                                }
2074                        }
2075                        return $range;
2076                }
2077
2078                function get_week_label()
2079                {
2080                        $first = $GLOBALS['phpgw']->datetime->gmtdate($GLOBALS['phpgw']->datetime->get_weekday_start($this->year, $this->month, $this->day));
2081                        $last = $GLOBALS['phpgw']->datetime->gmtdate($first['raw'] + 518400);
2082
2083                        return ($this->long_date($first,$last));
2084                }
2085
2086                function normalizeminutes(&$minutes)
2087                {
2088                        $hour = 0;
2089                        $min = (int)$minutes;
2090                        if($min >= 60)
2091                        {
2092                                $hour += $min / 60;
2093                                $min %= 60;
2094                        }
2095                        settype($minutes,'integer');
2096                        $minutes = $min;
2097                        return $hour;
2098                }
2099
2100                function splittime($time,$follow_24_rule=True)
2101                {
2102                        $temp = array('hour','minute','second','ampm');
2103                        $time = strrev($time);
2104                        $second = (int)(strrev(substr($time,0,2)));
2105                        $minute = (int)(strrev(substr($time,2,2)));
2106                        $hour   = (int)(strrev(substr($time,4)));
2107                        $hour += $this->normalizeminutes($minute);
2108                        $temp['second'] = $second;
2109                        $temp['minute'] = $minute;
2110                        $temp['hour']   = $hour;
2111                        $temp['ampm']   = '  ';
2112                        if($follow_24_rule == True)
2113                        {
2114                                if ($this->prefs['common']['timeformat'] == '24')
2115                                {
2116                                        return $temp;
2117                                }
2118
2119                                $temp['ampm'] = 'am';
2120
2121                                if ((int)$temp['hour'] > 12)
2122                                {
2123                                        $temp['hour'] = (int)((int)$temp['hour'] - 12);
2124                                        $temp['ampm'] = 'pm';
2125                                }
2126                                elseif ((int)$temp['hour'] == 12)
2127                                {
2128                                        $temp['ampm'] = 'pm';
2129                                }
2130                        }
2131                        return $temp;
2132                }
2133
2134                function get_exception_array($exception_str='')
2135                {
2136                        $exception = Array();
2137                        if(strpos(' '.$exception_str,','))
2138                        {
2139                                $exceptions = explode(',',$exception_str);
2140                $exceptions_count = count($exceptions);
2141                                for($exception_count=0;$exception_count<$exceptions_count;++$exception_count)
2142                                {
2143                                        $exception[] = (int)$exceptions[$exception_count];
2144                                }
2145                        }
2146                        elseif($exception_str != '')
2147                        {
2148                                $exception[] = (int)$exception_str;
2149                        }
2150                        return $exception;
2151                }
2152
2153                function build_time_for_display($fixed_time)
2154                {
2155                        $time = $this->splittime($fixed_time);
2156                        $str = $time['hour'].':'.((int)$time['minute']<=9?'0':'').$time['minute'];
2157
2158                        if ($this->prefs['common']['timeformat'] == '12')
2159                        {
2160                                $str .= ' ' . $time['ampm'];
2161                        }
2162
2163                        return $str;
2164                }
2165
2166                function sort_event($event,$date)
2167                {
2168                        $inserted = False;
2169                        if(isset($event['recur_exception']))
2170                        {
2171                                $event_time = mktime($event['start']['hour'],$event['start']['min'],0,(int)(substr($date,4,2)),(int)(substr($date,6,2)),(int)(substr($date,0,4))) - $GLOBALS['phpgw']->datetime->tz_offset;
2172                                while($inserted == False && list($key,$exception_time) = each($event['recur_exception']))
2173                                {
2174                                        if($this->debug)
2175                                        {
2176                                                echo '<!-- checking exception datetime '.$exception_time.' to event datetime '.$event_time.' -->'."\n";
2177                                        }
2178                                        if($exception_time == $event_time)
2179                                        {
2180                                                $inserted = True;
2181                                        }
2182                                }
2183                        }
2184                        if($this->cached_events[$date] && $inserted == False)
2185                        {
2186
2187                                if($this->debug)
2188                                {
2189                                        echo '<!-- Cached Events found for '.$date.' -->'."\n";
2190                                }
2191                                $year = substr($date,0,4);
2192                                $month = substr($date,4,2);
2193                                $day = substr($date,6,2);
2194
2195                                if($this->debug)
2196                                {
2197                                        echo '<!-- Date : '.$date.' Count : '.count($this->cached_events[$date]).' -->'."\n";
2198                                }
2199
2200                $cached_events_count = count($this->cached_events[$date]);
2201                                for($i=0;$i<$cached_events_count;++$i)
2202                                {
2203                                        if($this->cached_events[$date][$i]['id'] == $event['id'] || $this->cached_events[$date][$i]['reference'] == $event['id'])
2204                                        {
2205                                                if($this->debug)
2206                                                {
2207                                                        echo '<!-- Item already inserted! -->'."\n";
2208                                                }
2209                                                $inserted = True;
2210                                                break;
2211                                        }
2212                                        /* This puts all spanning events across multiple days up at the top. */
2213                                        if($this->cached_events[$date][$i]['recur_type'] == MCAL_RECUR_NONE)
2214                                        {
2215                                                if($this->cached_events[$date][$i]['start']['mday'] != $day && $this->cached_events[$date][$i]['end']['mday'] >= $day)
2216                                                {
2217                                                        continue;
2218                                                }
2219                                        }
2220                                        if(date('Hi',mktime($event['start']['hour'],$event['start']['min'],$event['start']['sec'],$month,$day,$year)) < date('Hi',mktime($this->cached_events[$date][$i]['start']['hour'],$this->cached_events[$date][$i]['start']['min'],$this->cached_events[$date][$i]['start']['sec'],$month,$day,$year)))
2221                                        {
2222                                                for($j=count($this->cached_events[$date]);$j>=$i;$j--)
2223                                                {
2224                                                        $this->cached_events[$date][$j] = $this->cached_events[$date][$j-1];
2225                                                }
2226                                                if($this->debug)
2227                                                {
2228                                                        echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
2229                                                }
2230                                                $inserted = True;
2231                                                $this->cached_events[$date][$i] = $event;
2232                                                break;
2233                                        }
2234                                }
2235                        }
2236                        if(!$inserted)
2237                        {
2238                                if($this->debug)
2239                                {
2240                                        echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
2241                                }
2242                                $this->cached_events[$date][] = $event;
2243                        }
2244                }
2245
2246                function check_repeating_events($datetime)
2247                {
2248                        @reset($this->repeating_events);
2249                        $search_date_full = date('Ymd',$datetime);
2250                        $search_date_year = date('Y',$datetime);
2251                        $search_date_month = date('m',$datetime);
2252                        $search_date_day = date('d',$datetime);
2253                        $search_date_dow = date('w',$datetime);
2254                        $search_beg_day = mktime(0,0,0,$search_date_month,$search_date_day,$search_date_year);
2255                        if($this->debug)
2256                        {
2257                                echo '<!-- Search Date Full = '.$search_date_full.' -->'."\n";
2258                        }
2259                        $repeated = $this->repeating_events;
2260                        $r_events = count($repeated);
2261                        for ($i=0;$i<$r_events;++$i)
2262                        {
2263                                $rep_events = $this->repeating_events[$i];
2264                                $id = $rep_events['id'];
2265                                $event_beg_day = mktime(0,0,0,$rep_events['start']['month'],$rep_events['start']['mday'],$rep_events['start']['year']);
2266                                if($rep_events['recur_enddate']['month'] != 0 && $rep_events['recur_enddate']['mday'] != 0 && $rep_events['recur_enddate']['year'] != 0)
2267                                {
2268                                        $event_recur_time = $this->maketime($rep_events['recur_enddate']);
2269                                }
2270                                else
2271                                {
2272                                        $event_recur_time = mktime(0,0,0,1,1,2030);
2273                                }
2274                                $end_recur_date = date('Ymd',$event_recur_time);
2275                                $full_event_date = date('Ymd',$event_beg_day);
2276
2277                                if($this->debug)
2278                                {
2279                                        echo '<!-- check_repeating_events - Processing ID - '.$id.' -->'."\n";
2280                                        echo '<!-- check_repeating_events - Recurring End Date - '.$end_recur_date.' -->'."\n";
2281                                }
2282
2283                                // only repeat after the beginning, and if there is an rpt_end before the end date
2284                                if (($search_date_full > $end_recur_date) || ($search_date_full < $full_event_date))
2285                                {
2286                                        continue;
2287                                }
2288
2289                                if ($search_date_full == $full_event_date)
2290                                {
2291                                        $this->sort_event($rep_events,$search_date_full);
2292                                        continue;
2293                                }
2294                                else
2295                                {
2296                                        $freq = $rep_events['recur_interval'];
2297                                        $freq = $freq ? $freq : 1;
2298                                        $type = $rep_events['recur_type'];
2299                                        switch($type)
2300                                        {
2301                                                case MCAL_RECUR_DAILY:
2302                                                        if($this->debug)
2303                                                        {
2304                                                                echo '<!-- check_repeating_events - MCAL_RECUR_DAILY - '.$id.' -->'."\n";
2305                                                        }
2306                                                       
2307                                                        if ($freq == 1 && $rep_events['recur_enddate']['month'] != 0 && $rep_events['recur_enddate']['mday'] != 0 && $rep_events['recur_enddate']['year'] != 0 && $search_date_full <= $end_recur_date)
2308                                                        {
2309                                                                $this->sort_event($rep_events,$search_date_full);
2310                                                        }
2311                                                        elseif (floor(($search_beg_day - $event_beg_day)/86400) % ($freq ? $freq : 1))
2312                                                        {
2313                                                                continue;
2314                                                        }
2315                                                        else
2316                                                        {
2317                                                                $this->sort_event($rep_events,$search_date_full);
2318                                                        }
2319                                                        break;
2320                                                case MCAL_RECUR_WEEKLY:
2321                                                        if ((floor($search_beg_day / 604800) - floor($event_beg_day / 604800)) % $freq)
2322                                                        {
2323                                                                continue;
2324                                                        }
2325                                                        $check = 0;
2326                                                        switch($search_date_dow)
2327                                                        {
2328                                                                case 0:
2329                                                                        $check = MCAL_M_SUNDAY;
2330                                                                        break;
2331                                                                case 1:
2332                                                                        $check = MCAL_M_MONDAY;
2333                                                                        break;
2334                                                                case 2:
2335                                                                        $check = MCAL_M_TUESDAY;
2336                                                                        break;
2337                                                                case 3:
2338                                                                        $check = MCAL_M_WEDNESDAY;
2339                                                                        break;
2340                                                                case 4:
2341                                                                        $check = MCAL_M_THURSDAY;
2342                                                                        break;
2343                                                                case 5:
2344                                                                        $check = MCAL_M_FRIDAY;
2345                                                                        break;
2346                                                                case 6:
2347                                                                        $check = MCAL_M_SATURDAY;
2348                                                                        break;
2349                                                        }
2350                                                        if ($rep_events['recur_data'] & $check)
2351                                                        {
2352                                                                $this->sort_event($rep_events,$search_date_full);
2353                                                        }
2354                                                        break;
2355                                                case MCAL_RECUR_MONTHLY_WDAY:
2356                                                        if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month']) % $freq)
2357                                                        {
2358                                                                continue;
2359                                                        }
2360
2361                                                        if (($GLOBALS['phpgw']->datetime->day_of_week($rep_events['start']['year'],$rep_events['start']['month'],$rep_events['start']['mday']) == $GLOBALS['phpgw']->datetime->day_of_week($search_date_year,$search_date_month,$search_date_day)) &&
2362                                                                (ceil($rep_events['start']['mday']/7) == ceil($search_date_day/7)))
2363                                                        {
2364                                                                $this->sort_event($rep_events,$search_date_full);
2365                                                        }
2366                                                        break;
2367                                                case MCAL_RECUR_MONTHLY_MDAY:
2368                                                        if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month'])  % ($freq ? $freq : 1))
2369                                                        {
2370                                                                continue;
2371                                                        }
2372                                                        if ($search_date_day == $rep_events['start']['mday'])
2373                                                        {
2374                                                                $this->sort_event($rep_events,$search_date_full);
2375                                                        }
2376                                                        break;
2377                                                case MCAL_RECUR_YEARLY:
2378                                                        if (($search_date_year - $rep_events['start']['year']) % ($freq ? $freq : 1))
2379                                                        {
2380                                                                continue;
2381                                                        }
2382                                                        if (date('dm',$datetime) == date('dm',$event_beg_day))
2383                                                        {
2384                                                                $this->sort_event($rep_events,$search_date_full);
2385                                                        }
2386                                                        break;
2387                                        }
2388                                }
2389                        }       // end for loop
2390                }       // end function
2391
2392                function store_to_cache($params)
2393                {
2394                        if(!is_array($params))
2395                        {
2396                                return False;
2397                        }
2398                        if (isset($params['start']) && ($datearr = $GLOBALS['server']->iso86012date($params['start'])))
2399                        {
2400                                $syear = $datearr['year'];
2401                                $smonth = $datearr['month'];
2402                                $sday = $datearr['mday'];
2403                                $this->xmlrpc = True;
2404                        }
2405                        else
2406                        {
2407                                $syear = $params['syear'];
2408                                $smonth = $params['smonth'];
2409                                $sday = $params['sday'];
2410                        }
2411                        if (isset($params['end']) && ($datearr = $GLOBALS['server']->iso86012date($params['end'])))
2412                        {
2413                                $eyear = $datearr['year'];
2414                                $emonth = $datearr['month'];
2415                                $eday = $datearr['mday'];
2416                                $this->xmlrpc = True;
2417                        }
2418                        else
2419                        {
2420                                $eyear = (isset($params['eyear'])?$params['eyear']:0);
2421                                $emonth = (isset($params['emonth'])?$params['emonth']:0);
2422                                $eday = (isset($params['eday'])?$params['eday']:0);
2423                        }
2424                        if (!isset($params['owner']) && @$this->xmlrpc)
2425                        {
2426                                $owner_id = $GLOBALS['phpgw_info']['user']['user_id'];
2427                        }
2428                        else
2429                        {
2430                                $owner_id = (isset($params['owner'])?$params['owner']:0);
2431                                if($owner_id==0 && $this->is_group)
2432                                {
2433                                        unset($owner_id);
2434                                        $owner_id = $this->g_owner;
2435                                        if($this->debug)
2436                                        {
2437                                                echo '<!-- owner_id in ('.implode(',',$owner_id).') -->'."\n";
2438                                        }
2439                                }
2440                        }
2441                        if(!$eyear && !$emonth && !$eday)
2442                        {
2443                                $edate = mktime(23,59,59,$smonth + 1,$sday + 1,$syear);
2444                                $eyear = date('Y',$edate);
2445                                $emonth = date('m',$edate);
2446                                $eday = date('d',$edate);
2447                        }
2448                        else
2449                        {
2450                                if(!$eyear)
2451                                {
2452                                        $eyear = $syear;
2453                                }
2454                                //Tratamento do valor final (mes) da pesquisa de eventos feita em $this->so->list_events.
2455                                //Se $emonth nao tem valor, recebe o valor de $smonth (que recebe $params['smonth']) e soma 1.
2456                                //O valor $params['emonth'] indica o mes final para a pesquisa de eventos, e passou a ser
2457                                //informado na a impressao de eventos mensais. Mudancas feitas em class.uicalendar.inc.php,
2458                                //function display_month_print();
2459                                if(!$emonth)
2460                                {
2461                                        $emonth = $smonth + 1;
2462                                        if($emonth > 12)
2463                                        {
2464                                                $emonth = 1;
2465                                                ++$eyear;
2466                                        }
2467                                }
2468                                if(!$eday)
2469                                {
2470                                        $eday = $sday + 1;
2471                                }
2472                                $edate = mktime(23,59,59,$emonth,$eday,$eyear);
2473                        }
2474                        //echo "<p>bocalendar::store_to_cache(".print_r($params,True).") syear=$syear, smonth=$smonth, sday=$sday, eyear=$eyear, emonth=$emonth, eday=$eday, xmlrpc='$param[xmlrpc]'</p>\n";
2475                        if($this->debug)
2476                        {
2477                                echo '<!-- Start Date : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2478                                echo '<!-- End   Date : '.sprintf("%04d%02d%02d",$eyear,$emonth,$eday).' -->'."\n";
2479                        }
2480                        //A variavel $month_print recebe o parametro 'saux' com o mes de inicio da pesquisa de eventos por
2481                        //$this->so->list_events. O valor do mes final da pesquisa e tratado no codigo acima;
2482                        //$month_ini = $params['saux'];
2483
2484                        if($owner_id)
2485                        {
2486                                $cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
2487                                $cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
2488                        }
2489                        else
2490                        {
2491                                $cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
2492                                $cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
2493                        }
2494
2495                        $c_cached_ids = count($cached_event_ids);
2496                        $c_cached_ids_repeating = count($cached_event_ids_repeating);
2497
2498                        if($this->debug)
2499                        {
2500                                echo '<!-- events cached : '.$c_cached_ids.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2501                                echo '<!-- repeating events cached : '.$c_cached_ids_repeating.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2502                        }
2503
2504                        $this->cached_events = Array();
2505
2506                        if($c_cached_ids == 0 && $c_cached_ids_repeating == 0)
2507                        {
2508                                return;
2509                        }
2510
2511                        $cache_start = (int)(sprintf("%04d%02d%02d",$syear,$smonth,$sday));
2512                        $cached_event=$this->get_cached_event();
2513                        if($c_cached_ids)
2514                        {
2515                                for($i=0;$i<$c_cached_ids;++$i)
2516                                {
2517                                        $event = $this->so->read_entry($cached_event_ids[$i]);
2518                                        if ($event['recur_type'])
2519                                        {
2520                                                continue;       // fetch recuring events only in 2. loop
2521                                        }
2522                                        $startdate = (int)(date('Ymd',$this->maketime($event['start'])));
2523                                        $enddate = (int)(date('Ymd',$this->maketime($event['end'])));
2524                                        $this->cached_events[$startdate][] = $event;
2525                                        if($startdate != $enddate)
2526                                        {
2527                                                $start['year'] = (int)(substr($startdate,0,4));
2528                                                $start['month'] = (int)(substr($startdate,4,2));
2529                                                $start['mday'] = (int)(substr($startdate,6,2));
2530                                                for($j=$startdate,$k=0;$j<=$enddate;++$k,$j=(int)(date('Ymd',mktime(0,0,0,$start['month'],$start['mday'] + $k,$start['year']))))
2531                                                {
2532                                                        $c_evt_day = count($this->cached_events[$j]) - 1;
2533                                                        if($c_evt_day < 0)
2534                                                        {
2535                                                                $c_evt_day = 0;
2536                                                        }
2537                                                        if($this->debug)
2538                                                        {
2539                                                                echo '<!-- Date: '.$j.' Count : '.$c_evt_day.' -->'."\n";
2540                                                        }
2541                                                        if($this->cached_events[$j][$c_evt_day]['id'] != $event['id'])
2542                                                        {
2543                                                                if($this->debug)
2544                                                                {
2545                                                                        echo '<!-- Adding Event for Date: '.$j.' -->'."\n";
2546                                                                }
2547                                                                $this->cached_events[$j][] = $event;
2548                                                        }
2549                                                        if ($j >= $cache_start && (@$params['no_doubles'] || @$this->xmlrpc))
2550                                                        {
2551                                                                break;  // add event only once on it's startdate
2552                                                        }
2553                                                }
2554                                        }
2555                                }
2556                        }
2557
2558                        $this->repeating_events = Array();
2559                        if($c_cached_ids_repeating)
2560                        {
2561                                for($i=0;$i<$c_cached_ids_repeating;++$i)
2562                                {
2563                                        $this->repeating_events[$i] = $this->so->read_entry($cached_event_ids_repeating[$i]);
2564                                        if($this->debug)
2565                                        {
2566                                                echo '<!-- Cached Events ID: '.$cached_event_ids_repeating[$i].' ('.sprintf("%04d%02d%02d",$this->repeating_events[$i]['start']['year'],$this->repeating_events[$i]['start']['month'],$this->repeating_events[$i]['start']['mday']).') -->'."\n";
2567                                        }
2568                                }
2569                                for($date=mktime(0,0,0,$smonth,$sday,$syear);$date<=$edate;$date += 86400)
2570                                {
2571                                        if($this->debug)
2572                                        {
2573                                                $search_date = date('Ymd',$date);
2574                                                echo '<!-- Calling check_repeating_events('.$search_date.') -->'."\n";
2575                                        }
2576                                        $this->check_repeating_events($date);
2577                                        if($this->debug)
2578                                        {
2579                                                echo '<!-- Total events found matching '.$search_date.' = '.count($this->cached_events[$search_date]).' -->'."\n";
2580                        $cached_events_count = count($this->cached_events[$search_date]);
2581                                                for($i=0;$i<$cached_events_count;++$i)
2582                                                {
2583                                                        echo '<!-- Date: '.$search_date.' ['.$i.'] = '.$this->cached_events[$search_date][$i]['id'].' -->'."\n";
2584                                                }
2585                                        }
2586                                }
2587                        }
2588                        $retval = Array();
2589                        for($j=date('Ymd',mktime(0,0,0,$smonth,$sday,$syear)),$k=0;$j<=date('Ymd',mktime(0,0,0,$emonth,$eday,$eyear));++$k,$j=date('Ymd',mktime(0,0,0,$smonth,$sday + $k,$syear)))
2590                        {
2591                                if(is_array($this->cached_events[$j]))
2592                                {
2593                                        if ($this->xmlrpc)
2594                                        {
2595                                                foreach($this->cached_events[$j] as $event)
2596                                                {
2597                                                        $retval[] = $this->xmlrpc_prepare($event);
2598                                                }
2599                                        }
2600                                        else
2601                                        {
2602                                                $retval[$j] = $this->cached_events[$j];
2603                                        }
2604                                }
2605                        }
2606                        //echo "store_to_cache(".print_r($params,True).")=<pre>".print_r($retval,True)."</pre>\n";
2607                        $this->so->cal->event = $cached_event;
2608                        return $retval;
2609                }
2610
2611                function xmlrpc_prepare(&$event)
2612                {
2613                        $event['rights'] = $this->grants[$event['owner']];
2614
2615                        foreach(array('start','end','modtime','recur_enddate') as $name)
2616                        {
2617                                if (isset($event[$name]))
2618                                {
2619                                        $event[$name] = $GLOBALS['server']->date2iso8601($event[$name]);
2620                                }
2621                        }
2622                        if (is_array($event['recur_exception']))
2623                        {
2624                                foreach($event['recur_exception'] as $key => $timestamp)
2625                                {
2626                                        $event['recur_exception'][$key] = $GLOBALS['server']->date2iso8601($timestamp);
2627                                }
2628                        }
2629                        static $user_cache = array();
2630
2631                        if (!is_object($GLOBALS['phpgw']->perferences))
2632                        {
2633                                $GLOBALS['phpgw']->perferences = CreateObject('phpgwapi.preferences');
2634                        }
2635                        foreach($event['participants'] as $user_id => $status)
2636                        {
2637                                if (!isset($user_cache[$user_id]))
2638                                {
2639                                        $user_cache[$user_id] = array(
2640                                                'name'   => $GLOBALS['phpgw']->common->grab_owner_name($user_id),
2641                                                'email'  => $GLOBALS['phpgw']->perferences->email_address($user_id)
2642                                        );
2643                                }
2644                                $event['participants'][$user_id] = $user_cache[$user_id] + array(
2645                                        'status' => $status,
2646                                );
2647                        }
2648                        if (is_array($event['alarm']))
2649                        {
2650                                foreach($event['alarm'] as $id => $alarm)
2651                                {
2652                                        $event['alarm'][$id]['time'] = $GLOBALS['server']->date2iso8601($alarm['time']);
2653                                        if ($alarm['owner'] != $GLOBALS['phpgw_info']['user']['account_id'])
2654                                        {
2655                                                unset($event['alarm'][$id]);
2656                                        }
2657                                }
2658                        }
2659                        $event['category'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$event['category']));
2660
2661                        // using access={public|privat} in all modules via xmlrpc
2662                        $event['access'] = $event['public'] ? 'public' : 'privat';
2663                        unset($event['public']);
2664
2665                        return $event;
2666                }
2667
2668                /* Begin Appsession Data */
2669                function store_to_appsession($event)
2670                {
2671                        $GLOBALS['phpgw']->session->appsession('entry','calendar',$event);
2672                }
2673
2674                function restore_from_appsession()
2675                {
2676                        $this->event_init();
2677                        $event = $GLOBALS['phpgw']->session->appsession('entry','calendar');
2678                        $this->so->cal->event = $event;
2679                        return $event;
2680                }
2681                /* End Appsession Data */
2682
2683                /* Begin of SO functions */
2684                function get_cached_event()
2685                {
2686                        return $this->so->get_cached_event();
2687                }
2688
2689                function add_attribute($var,$value,$index='**(**')
2690                {
2691                        $this->so->add_attribute($var,$value,$index);
2692                }
2693
2694                function event_init()
2695                {
2696                        $this->so->event_init();
2697                }
2698
2699                function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
2700                {
2701                        $this->so->set_start($year,$month,$day,$hour,$min,$sec);
2702                }
2703
2704                function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
2705                {
2706                        $this->so->set_end($year,$month,$day,$hour,$min,$sec);
2707                }
2708
2709                function set_title($title='')
2710                {
2711                        $this->so->set_title($title);
2712                }
2713
2714                function set_description($description='')
2715                {
2716                        $this->so->set_description($description);
2717                }
2718                function set_ex_participants($ex_participants='')
2719                {
2720                        $this->so->set_ex_participants($ex_participants);
2721                }
2722
2723                function set_class($class)
2724                {
2725                        $this->so->set_class($class);
2726                }
2727
2728                function set_category($category='')
2729                {
2730                        $this->so->set_category($category);
2731                }
2732
2733                function set_alarm($alarm)
2734                {
2735                        $this->so->set_alarm($alarm);
2736                }
2737
2738                function set_recur_none()
2739                {
2740                        $this->so->set_recur_none();
2741                }
2742
2743                function set_recur_daily($year,$month,$day,$interval)
2744                {
2745                        $this->so->set_recur_daily($year,$month,$day,$interval);
2746                }
2747
2748                function set_recur_weekly($year,$month,$day,$interval,$weekdays)
2749                {
2750                        $this->so->set_recur_weekly($year,$month,$day,$interval,$weekdays);
2751                }
2752
2753                function set_recur_monthly_mday($year,$month,$day,$interval)
2754                {
2755                        $this->so->set_recur_monthly_mday($year,$month,$day,$interval);
2756                }
2757
2758                function set_recur_monthly_wday($year,$month,$day,$interval)
2759                {
2760                        $this->so->set_recur_monthly_wday($year,$month,$day,$interval);
2761                }
2762
2763                function set_recur_yearly($year,$month,$day,$interval)
2764                {
2765                        $this->so->set_recur_yearly($year,$month,$day,$interval);
2766                }
2767                /* End of SO functions */
2768
2769                function prepare_matrix($interval,$increment,$part,$fulldate)
2770                {
2771                        for($h=0;$h<24;++$h)
2772                        {
2773                                for($m=0;$m<$interval;++$m)
2774                                {
2775                                        $index = (($h * 10000) + (($m * $increment) * 100));
2776                                        $time_slice[$index]['marker'] = '&nbsp';
2777                                        $time_slice[$index]['description'] = '';
2778                                }
2779                        }
2780                        foreach($this->cached_events[$fulldate] as $event)
2781                        {
2782                                if ($event['participants'][$part] == 'R')
2783                                {
2784                                        continue;       // dont show rejected invitations, as they are free time
2785                                }
2786                                $eventstart = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset);
2787                                $eventend = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset);
2788                                $start = ($eventstart['hour'] * 10000) + ($eventstart['minute'] * 100);
2789                                $starttemp = $this->splittime("$start",False);
2790                                $subminute = 0;
2791                                for($m=0;$m<$interval;++$m)
2792                                {
2793                                        $minutes = $increment * $m;
2794                                        if((int)$starttemp['minute'] > $minutes && (int)$starttemp['minute'] < ($minutes + $increment))
2795                                        {
2796                                                $subminute = ($starttemp['minute'] - $minutes) * 100;
2797                                        }
2798                                }
2799                                $start -= $subminute;
2800                                $end =  ($eventend['hour'] * 10000) + ($eventend['minute'] * 100);
2801                                $endtemp = $this->splittime("$end",False);
2802                                $addminute = 0;
2803                                for($m=0;$m<$interval;++$m)
2804                                {
2805                                        $minutes = ($increment * $m);
2806                                        if($endtemp['minute'] < ($minutes + $increment) && $endtemp['minute'] > $minutes)
2807                                        {
2808                                                $addminute = ($minutes + $increment - $endtemp['minute']) * 100;
2809                                        }
2810                                }
2811                                $end += $addminute;
2812                                $starttemp = $this->splittime("$start",False);
2813                                $endtemp = $this->splittime("$end",False);
2814
2815                                for($h=$starttemp['hour'];$h<=$endtemp['hour'];++$h)
2816                                {
2817                                        $startminute = 0;
2818                                        $endminute = $interval;
2819                                        $hour = $h * 10000;
2820                                        if($h == (int)$starttemp['hour'])
2821                                        {
2822                                                $startminute = ($starttemp['minute'] / $increment);
2823                                        }
2824                                        if($h == (int)$endtemp['hour'])
2825                                        {
2826                                                $endminute = ($endtemp['minute'] / $increment);
2827                                        }
2828                                        $private = $this->is_private($event,$part);
2829                                        $time_display = $GLOBALS['phpgw']->common->show_date($eventstart['raw'],$this->users_timeformat).'-'.$GLOBALS['phpgw']->common->show_date($eventend['raw'],$this->users_timeformat);
2830                                        $time_description = '('.$time_display.') '.$this->get_short_field($event,$private,'title').$this->display_status($event['participants'][$part]);
2831                                        for($m=$startminute;$m<$endminute;++$m)
2832                                        {
2833                                                $index = ($hour + (($m * $increment) * 100));
2834                                                $time_slice[$index]['marker'] = '-';
2835                                                $time_slice[$index]['description'] = $time_description;
2836                                                $time_slice[$index]['id'] = $event['id'];
2837                                        }
2838                                }
2839                        }
2840                        return $time_slice;
2841                }
2842
2843                /*!
2844                @function set_status
2845                @abstract set the participant response $status for event $cal_id and notifies the owner of the event
2846                */
2847                function set_status($cal_id,$status,$user = false)
2848                {
2849                        $status2msg = array(
2850                                REJECTED  => MSG_REJECTED,
2851                                TENTATIVE => MSG_TENTATIVE,
2852                                ACCEPTED  => MSG_ACCEPTED
2853                        );
2854                        if (!isset($status2msg[$status]))
2855                        {
2856                                return False;
2857                        }
2858                        $event = $this->so->read_entry($cal_id);
2859                        if($user) $account_id = $user;
2860                        else $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
2861                        if(($status2msg[$status] == "5" && $event['participants'][$account_id] == "A") ||
2862                         ($status2msg[$status] == "3" && $event['participants'][$account_id] == "R")) {
2863                                return True;
2864                        }
2865                        $this->so->set_status($cal_id,$status,$account_id);
2866                        $event = $this->so->read_entry($cal_id);
2867                        $this->send_update($status2msg[$status],$event['participants'],$event,false,$account_id);
2868
2869                        $sts = array_values( $event['participants'] );
2870
2871                        //verifica se todos os participantes rejeitaram o evento
2872            $sts_count = count($sts);
2873                        for($i = 0; $i < $sts_count; ++$i ){
2874                                if( $sts[i] === "R")
2875                                        unset( $sts[i] );
2876                        }
2877                       
2878                        if( empty( $sts ) )
2879                        {
2880                                $this->so->delete_entry( $cal_id );
2881                                $this->so->expunge();
2882                        }
2883                }
2884
2885                /*!
2886                @function update_requested
2887                @abstract checks if $userid has requested (in $part_prefs) updates for $msg_type
2888                @syntax update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2889                @param $userid numerical user-id
2890                @param $part_prefs preferces of the user $userid
2891                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
2892                @param $old_event Event before the change
2893                @param $new_event Event after the change
2894                @returns 0 = no update requested, > 0 update requested
2895                */
2896                function update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2897                {
2898                        if ($msg_type == MSG_ALARM)
2899                        {
2900                                return True;    // always True for now
2901                        }
2902                        $want_update = 0;
2903
2904                        // the following switch fall-through all cases, as each included the following too
2905                        //
2906                        $msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE;
2907
2908                        switch($ru = $part_prefs['calendar']['receive_updates'])
2909                        {
2910                                case 'responses':
2911                                        if ($msg_is_response)
2912                                        {
2913                                                ++$want_update;
2914                                        }
2915                                case 'modifications':
2916                                        if ($msg_type == MSG_MODIFIED)
2917                                        {
2918                                                ++$want_update;
2919                                        }
2920                                case 'time_change_4h':
2921                                case 'time_change':
2922                                        $diff = max(abs($this->maketime($old_event['start'])-$this->maketime($new_event['start'])),
2923                                                abs($this->maketime($old_event['end'])-$this->maketime($new_event['end'])));
2924                                        $check = $ru == 'time_change_4h' ? 4 * 60 * 60 - 1 : 0;
2925                                        if ($msg_type == MSG_MODIFIED && $diff > $check)
2926                                        {
2927                                                ++$want_update;
2928                                        }
2929                                case 'add_cancel':
2930                                        if ($old_event['owner'] == $userid && $msg_is_response ||
2931                                                $msg_type == MSG_DELETED || $msg_type == MSG_ADDED)
2932                                        {
2933                                                ++$want_update;
2934                                        }
2935                                        break;
2936                                case 'no':
2937                                        break;
2938                        }
2939                        //echo "<p>bocalendar::update_requested(user=$userid,pref=".$part_prefs['calendar']['receive_updates'] .",msg_type=$msg_type,".($old_event?$old_event['title']:'False').",".($old_event?$old_event['title']:'False').") = $want_update</p>\n";
2940                        return $want_update > 0;
2941                }
2942
2943
2944                function create_vcard($event_arrays , $metodo = 'PUBLISH', $externo = false,$importAccount = false)
2945                {
2946                    if(!$importAccount)
2947                        $importAccount['mail'] = $GLOBALS['phpgw_info']['user']['email'];
2948
2949                    if(!is_array($event_arrays))
2950                                return null;
2951
2952                    $tmpattach="BEGIN:VCALENDAR\r\n"
2953                        ."PRODID:-//Expresso Livre//Calendar//EN\r\n"
2954                        ."VERSION:2.0\r\n"
2955                        ."CALSCALE:GREGORIAN\r\n"
2956                        ."METHOD:".$metodo."\r\n";
2957
2958                    //$offset = ((int)substr(date('O',$GLOBALS['phpgw']->datetime->users_localtime), 0, 3));
2959                   
2960                    //Recupera o offset do cliente com base na diferenca entre o horario do cliente (timezone da preferencia)
2961                    //e o unixtime
2962                    //$offset = ((($GLOBALS['phpgw']->datetime->users_localtime) -  ($GLOBALS['phpgw']->datetime->gmtnow))/60)/60;
2963                   
2964                        $timezone = date('e');
2965
2966                        foreach ($event_arrays as $event_array)
2967                        {
2968                            $sy = $event_array['start']['year'];
2969                            $sm = $event_array['start']['month'];
2970                            $sd = $event_array['start']['mday'];
2971                            $sh = $event_array['start']['hour'];
2972                            $sn = $event_array['start']['min'];
2973                            $dtstart = sprintf("%04d%02d%02dT%02d%02d00", $sy, $sm, $sd, $sh, $sn);
2974
2975                            $ey = $event_array['end']['year'];
2976                            $em = $event_array['end']['month'];
2977                            $ed = $event_array['end']['mday'];
2978                            $eh = $event_array['end']['hour'];
2979                            $en = $event_array['end']['min'];
2980                            $dtend = sprintf("%04d%02d%02dT%02d%02d00", $ey, $em, $ed, $eh, $en);
2981
2982                            // Necessário espaços após quebra-de-linha, na descrição, caso contrário
2983                            // ocorrerá erro ao importar o agendamento no Outlook (erro lunar).
2984                            $description = str_replace("\n","\n ",$event_array['description']);
2985                            $tmpattach.="BEGIN:VEVENT\r\n";
2986                                                       
2987                            if(isset($event_array['organizer']) && $event_array['owner'] != -2)
2988                            {
2989                                $ldap = $this->getLdap(); 
2990                                $justthese = array("mail","cn");
2991                                $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$event_array['owner']."))";
2992                                $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
2993                                $entry = ldap_get_entries($ldap, $search);                                       
2994                                        $organizer = 'ORGANIZER;CN='.$entry[0]['cn'][0].':mailto:'.$entry[0]['mail'][0]."\r\n";
2995                                }   
2996                                else{   
2997                                        $email = explode('&lt;', $event_array['organizer']);
2998                                        $email2 = explode('&gt;', $email[1]);
2999                                $organizer = 'ORGANIZER;CN='.rtrim($email[0]).':mailto:'.$email2[0]."\r\n";
3000                                                        }
3001                                                                 
3002                            if(!$externo)
3003                            {
3004                                $tmpattach.=
3005                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
3006                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
3007                                ."LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3008                                                                .$organizer
3009                                ."UID:".$event_array['uid']."\r\n"
3010                                .$this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3011                                .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3012                                ."DESCRIPTION:".$description."\r\n"
3013                                ."SUMMARY:".$event_array['title']."\r\n"
3014                                ."LOCATION:".$event_array['location']."\r\n"
3015                                ."END:VEVENT\r\n";
3016                            }
3017                             else
3018                            {
3019                                $tmpattach.=
3020                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
3021                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
3022                                ."DTSTAMP:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3023                                .$organizer
3024                                .$this->mb_wordwrap("UID:".$event_array['uid']."\r\n",74,"\r\n ");
3025
3026                                switch ($metodo) {
3027                                    case 'PUBLISH':
3028                                          $tmpattach.=
3029                                             $this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3030                                                                                        .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3031                                            .$this->mb_wordwrap("DESCRIPTION:".$description."\r\n",74,"\r\n ")
3032                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3033                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ");
3034                                        break;
3035                                    case 'REPLY':
3036                                            $tmpattach.=
3037                                             $this->mb_wordwrap("ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUESTS=0:mailto:".$importAccount['mail']."\r\n",74,"\r\n ")
3038                                            .'DESCRIPTION:\n'."\r\n"
3039                                            .$this->mb_wordwrap("LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n",74,"\r\n ") //Hora no formato UTC
3040                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ")
3041                                            ."SEQUENCE:0\r\n"
3042                                            ."STATUS:CONFIRMED\r\n"
3043                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3044                                            ."TRANSP:OPAQUE\r\n";
3045                                        break;
3046                                    default:
3047                                           $tmpattach.=
3048                                             "DESCRIPTION:".$description."\r\n"
3049                                            ."SUMMARY:".$event_array['title']."\r\n"
3050                                            ."LOCATION:".$event_array['location']."\r\n";
3051                                        break;
3052                                }
3053                                  $tmpattach.= "END:VEVENT\r\n";
3054                            }
3055                           
3056                        }
3057                    $tmpattach.="END:VCALENDAR\r\n\r\n\r\n";   
3058                    return $tmpattach;
3059                }
3060
3061                function mb_wordwrap($str, $width=74, $break="\r\n")
3062                {
3063                    // Return short or empty strings untouched
3064                    if(empty($str) || mb_strlen($str, 'ISSO-8859-1') <= $width)
3065                        return $str;
3066
3067                    $br_width  = mb_strlen($break, 'ISSO-8859-1');
3068                    $str_width = mb_strlen($str, 'ISSO-8859-1');
3069                    $return = '';
3070                    $last_space = false;
3071
3072                    for($i=0, $count=0; $i < $str_width; ++$i, ++$count)
3073                    {
3074                        // If we're at a break
3075                        if (mb_substr($str, $i, $br_width, 'ISSO-8859-1') == $break)
3076                        {
3077                            $count = 0;
3078                            $return .= mb_substr($str, $i, $br_width, 'ISSO-8859-1');
3079                            $i += $br_width - 1;
3080                            continue;
3081                        }
3082
3083                        // Keep a track of the most recent possible break point
3084                        if(mb_substr($str, $i, 1, 'ISSO-8859-1') == " ")
3085                        {
3086                            $last_space = $i;
3087                        }
3088
3089                        // It's time to wrap
3090                        if ($count > $width)
3091                                {
3092                            // There are no spaces to break on!  Going to truncate :(
3093                            if(!$last_space)
3094                                    {
3095                                $return .= $break;
3096                                $count = 0;
3097                            }
3098                            else
3099                            {
3100                                // Work out how far back the last space was
3101                                $drop = $i - $last_space;
3102
3103                                // Cutting zero chars results in an empty string, so don't do that
3104                                if($drop > 0)
3105                                {
3106                                    $return = mb_substr($return, 0, -$drop);
3107                                }
3108
3109                                // Add a break
3110                                $return .= $break;
3111
3112                                // Update pointers
3113                                $i = $last_space + ($br_width - 1);
3114                                $last_space = false;
3115                                $count = 0;
3116                                    }
3117                                }
3118                               
3119                        // Add character from the input string to the output
3120                        $return .= mb_substr($str, $i, 1, 'ISSO-8859-1');
3121                    }
3122                    return $return;
3123                }
3124
3125                function getvCalendarParticipants($pExtParticipants,$pCalId)
3126                                {
3127                    $participants = explode(',', $pExtParticipants);
3128                    $return = '';
3129
3130                    foreach ($participants as $participant)
3131                                      {
3132                        $array = explode('"', $participant);
3133                        $mail = str_replace('<','', str_replace('>','',$array['2']));
3134                        if($mail && $array['1'])
3135                             $return .= 'ATTENDEE;CN='.$array['1'].';RSVP=TRUE:mailto:'.$mail."\r\n";
3136                    }
3137                    $db = $this->getDb();
3138                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3139                    $parts = array();
3140                    while($db->next_record())
3141                        array_push($parts, $db->row());
3142
3143                    $ldap = $this->getLdap();
3144                    foreach ($parts as $part)
3145                    {
3146                        $justthese = array('mail','cn');
3147                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3148                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3149                        $entry = ldap_get_entries($ldap, $search);
3150                        $return .= 'ATTENDEE;CN='.$entry[0]['cn'][0].';RSVP=TRUE:mailto:'.$entry[0]['mail'][0]."\r\n";
3151                                                        }
3152
3153                    return $return;
3154                                                        }
3155                               
3156                function getCalendarParticipantsArray($pCalId)
3157                {
3158                    $db = $this->getDb();
3159                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3160                    $parts = array();
3161                    while($db->next_record())
3162                        array_push($parts, $db->row());
3163
3164                    $ldap = $this->getLdap();
3165                    foreach ($parts as $part)
3166                    {
3167                        $justthese = array('mail','cn');
3168                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3169                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3170                        $entry = ldap_get_entries($ldap, $search);
3171                        $return [$entry[0]['mail'][0]] = array( 'CN'=> $entry[0]['cn'][0],'RSVP'=> 'TRUE' ,'ROLE' => 'REQ-PARTICIPANT');
3172                    }
3173                    return $return;
3174                }
3175
3176                function getvCalendarExternalParticipants($pCalId)
3177                {
3178
3179                    $db = $this->getDb();
3180                    $sql = "SELECT ex_participants FROM phpgw_cal WHERE cal_id = '$pCalId'";
3181                                $db->query($sql);
3182                               
3183                    $parts = array();
3184                    while($db->next_record())
3185                        array_push($parts, $db->row());
3186
3187                                        $participants = explode(',', $parts[0]['ex_participants']);
3188                    $return = '';
3189                                       
3190                                        $participants = unserialize(base64_decode($parts[0]['ex_participants']));
3191
3192                    foreach ($participants as $participant)
3193                    {   
3194                           $part = array();
3195
3196                           if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $participant['mail']))
3197                           {
3198                              $cn = null;
3199                              $mail = null;
3200                              preg_match ("(\"([^\"]*)\")", $participant['mail'], $cn);
3201                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3202
3203                              if($mail[1])
3204                              $part['mail'] =  $mail[1];
3205
3206                              if($cn[1])
3207                                $part['cn'] =  $cn[1];
3208
3209                                                         }
3210                                         else
3211                           if(preg_match("(<[^>]*@[^>]*>)", $participant['mail']))
3212                                                  {
3213                              $mail = null;
3214                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3215                              if($mail[1])
3216                                $part['mail'] =  $mail[1];
3217
3218                                                   }
3219                           else
3220                           if(preg_match("([^ ]*@[^ ]*)", $participant['mail']))
3221                           {
3222                              $mail = null;
3223                              preg_match ('([^ ]*@[^ ]*)', $participant['mail'], $mail);
3224                              if($mail[0])
3225                                $part['mail'] =  $mail[0];
3226
3227                           }
3228
3229                          if(count($part) > 0)
3230                          {
3231                              if($part['cn'])
3232                                                                $return .= 'ATTENDEE;CN='.$part['cn'].';RSVP=TRUE:mailto:'.$part['mail']."\r\n";
3233                              else
3234                                                                $return .= 'ATTENDEE;RSVP=TRUE:mailto:'.$part['mail']."\r\n"; 
3235                             
3236                                      }
3237                                }
3238
3239                    return $return;
3240                        }
3241
3242
3243                function getDb()
3244                {
3245                    include_once('../phpgwapi/inc/class.db.inc.php');
3246                    // Conecta ao banco de dados
3247                    if (is_array($_SESSION['phpgw_info']['expresso']['server']))
3248                        $GLOBALS['phpgw_info']['server'] = $_SESSION['phpgw_info']['expresso']['server'];
3249                    else
3250                        $_SESSION['phpgw_info']['expresso']['server'] = $GLOBALS['phpgw_info']['server'];
3251
3252                    $db = new db();
3253                    $db->Halt_On_Error = 'no';
3254                    $db->connect(
3255                                $_SESSION['phpgw_info']['expresso']['server']['db_name'],
3256                                $_SESSION['phpgw_info']['expresso']['server']['db_host'],
3257                                $_SESSION['phpgw_info']['expresso']['server']['db_port'],
3258                                $_SESSION['phpgw_info']['expresso']['server']['db_user'],
3259                                $_SESSION['phpgw_info']['expresso']['server']['db_pass'],
3260                                $_SESSION['phpgw_info']['expresso']['server']['db_type']
3261                                );
3262                                // Fim Conecta Banco de dados
3263                    return $db;
3264                }
3265
3266                function getLdap()
3267                {
3268                    require_once(dirname(__FILE__).'/../../header.inc.php');
3269                    require_once(dirname(__FILE__).'/../../phpgwapi/inc/class.common.inc.php');
3270   
3271                    $common = new common();
3272                               
3273                    if ( (!empty($GLOBALS['phpgw_info']['server']['ldap_master_host'])) &&
3274                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_dn'])) &&
3275                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_pw'])) )
3276                        {
3277                            $ldap = $common->ldapConnect($GLOBALS['phpgw_info']['server']['ldap_master_host'],
3278                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_dn'],
3279                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_pw']);
3280                        }
3281                        else
3282                        {
3283                            $ldap = $common->ldapConnect();
3284                        }
3285                       
3286                    return $ldap;
3287                }
3288
3289                function getvCalendarOrganizer($pOrganizer)
3290                {
3291
3292                   
3293                       $organizer = array();
3294       
3295                       if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $pOrganizer))
3296                       {
3297                          $cn = null;
3298                          $mail = null;
3299                          preg_match ("(\"([^\"]*)\")", $pOrganizer, $cn);
3300                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3301
3302                          if($mail[1])
3303                          $organizer['mail'] =  $mail[1];
3304
3305                          if($cn[1])
3306                            $organizer['cn'] =  $cn[1];
3307
3308                       }
3309                       else
3310                       if(preg_match("(<[^>]*@[^>]*>)", $pOrganizer))
3311                       {
3312                          $mail = null;
3313                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3314                          if($mail[1])
3315                            $organizer['mail'] =  $mail[1];
3316
3317                       }
3318                       else
3319                       if(preg_match("([^ ]*@[^ ]*)", $pOrganizer))
3320                       {
3321                          $mail = null;
3322                          preg_match ('([^ ]*@[^ ]*)', $pOrganizer, $mail);
3323                          if($mail[0])
3324                            $organizer['mail'] =  $mail[0];
3325
3326                       }
3327                       
3328                       if($organizer['cn']) $return = 'ORGANIZER;CN="'.$organizer['cn'].'":MAILTO:'.$organizer['mail']."\r\n";
3329                       else $return = 'ORGANIZER;MAILTO:'.$organizer['mail']."\r\n";
3330                       
3331                    return $return;
3332                }
3333
3334                /*!
3335                @function send_update
3336                @abstract sends update-messages to certain participants of an event
3337                @syntax send_update($msg_type,$to_notify,$old_event,$new_event=False)
3338                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
3339                @param $to_notify array with numerical user-ids as keys (!) (value is not used)
3340                @param $old_event Event before the change
3341                @param $new_event Event after the change
3342                */
3343                function send_update($msg_type,$to_notify,$old_event,$new_event = False, $user = False)
3344                        {
3345         
3346                        if (!is_array($to_notify)) $to_notify = array();
3347                        $owner = $old_event ? $old_event['owner'] : $new_event['owner'];
3348
3349                        if($owner === -2)
3350                            $to_notify[-2] = 'A';
3351
3352                        $version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
3353                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
3354                 
3355                        /*
3356                         * Caso o evento seja de uma conta compartilha busca obusca o cn e o email da conta
3357                         */
3358                        if($user)
3359                        {
3360                            $ldap = $this->getLdap(); 
3361                            $justthese = array("mail","cn");
3362                            $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3363                            $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3364                            $entry = ldap_get_entries($ldap, $search);
3365                            $sMail = $entry[0]['mail'][0];
3366                            $sCN = $entry[0]['cn'][0];
3367                            $sUN = $user;
3368                        }
3369                        else
3370                        {
3371                            $sMail = $GLOBALS['phpgw_info']['user']['email'];
3372                            $sCN = $GLOBALS['phpgw_info']['user']['fullname'];
3373                            $sUN = $GLOBALS['phpgw_info']['user']['account_id'];
3374                        }
3375                        //------------------------------------------------------------------------------------//
3376                 
3377                    $temp_tz_offset = $this->prefs['common']['tz_offset'];
3378                        $temp_timeformat = $this->prefs['common']['timeformat'];
3379                        $temp_dateformat = $this->prefs['common']['dateformat'];
3380                        $tz_offset = ((60 * 60) * (int)$temp_tz_offset);
3381
3382                        if($old_event != False)
3383                        {
3384                                $t_old_start_time = $this->maketime($old_event['start']);
3385                                if($t_old_start_time < (time() - 86400))
3386                                        return False;
3387                                }
3388
3389                        $temp_user = $GLOBALS['phpgw_info']['user'];
3390                        if (!$user) $user = $this->owner;
3391                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
3392                        $this->prefs = $GLOBALS['phpgw_info']['user']['preferences'];
3393
3394                        $event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
3395                        if($old_event != False)
3396                        {
3397                                $old_starttime = $t_old_start_time - $GLOBALS['phpgw']->datetime->tz_offset;
3398                        }
3399                        $starttime = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
3400                        $endtime   = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
3401
3402                        switch($msg_type)
3403                        {
3404                                case MSG_DELETED:
3405                                        $action = lang('Canceled');
3406                                        $msg = 'Canceled';
3407                                        $msgtype = '"calendar";';
3408                                        $method = 'cancel';
3409                                        $typesend = 1;
3410                                        break;
3411                                case MSG_MODIFIED:
3412                                        $action = lang('Modified');
3413                                        $msg = 'Modified';
3414                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3415                                        $method = 'request';
3416                                        $typesend = 2;
3417                                        break;
3418                                case MSG_ADDED:
3419                                        $action = lang('Added');
3420                                        $msg = 'Added';
3421                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3422                                        $method = 'request';
3423                                        $typesend = 3;
3424                                        break;
3425                                case MSG_REJECTED:
3426                                        $action = lang('Rejected');
3427                                        $msg = 'Response';
3428                                        $msgtype = '"calendar";';
3429                                        $method = 'reply';
3430                                        $typesend = 4;
3431                                        break;
3432                                case MSG_TENTATIVE:
3433                                        $action = lang('Tentative');
3434                                        $msg = 'Response';
3435                                        $msgtype = '"calendar";';
3436                                        $method = 'reply';
3437                                        $typesend = 5;
3438                                        break;
3439                                case MSG_ACCEPTED:
3440                                        $action = lang('Accepted');
3441                                        $msg = 'Response';
3442                                        $msgtype = '"calendar";';
3443                                        $method = 'reply';
3444                                        $typesend = 6;
3445                                        break;
3446                                case MSG_ALARM:
3447                                        $action = lang('Alarm');
3448                                        $msg = 'Alarm';
3449                                        $msgtype = '"calendar";';
3450                                        $method = 'publish';    // duno if thats right
3451                                        $typesend = 7;
3452                                        break;
3453                                default:
3454                                        $method = 'publish';
3455                                        $typesend = 8;
3456                        }
3457                        $notify_msg = $this->prefs['calendar']['notify'.$msg];
3458                        if (empty($notify_msg))
3459                                $notify_msg = $this->prefs['calendar']['notifyAdded'];  // use a default
3460                       
3461                        $details = array(                       // event-details for the notify-msg
3462                                'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
3463                                'action'      => $action,
3464                        );
3465                        $event_arr = $this->event2array($event);
3466                        foreach($event_arr as $key => $val)
3467                        {
3468                                $details[$key] = $val['data'];
3469                        }
3470                       
3471                        $details['participants'] = implode("\n",$details['participants']);
3472
3473                        $details['link'] = $GLOBALS['phpgw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uicalendar.view&cal_id='.$event['id'];
3474                        // if url is only a path, try guessing the rest ;-)
3475                        if ($GLOBALS['phpgw_info']['server']['webserver_url'][0] == '/')
3476                        {
3477                                $details['link'] = ($GLOBALS['phpgw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
3478                                        ($GLOBALS['phpgw_info']['server']['hostname'] ? $GLOBALS['phpgw_info']['server']['hostname'] : 'localhost').
3479                                        $details['link'];
3480                        }
3481                       
3482                        //Seta o email usando phpmailer
3483                        define('PHPGW_INCLUDE_ROOT','../');     
3484                        define('PHPGW_API_INC','../phpgwapi/inc');     
3485                        include_once(PHPGW_API_INC.'/class.phpmailer.inc.php');
3486                        $mail = new PHPMailer();
3487                        $mail->IsSMTP();
3488                        $boemailadmin = CreateObject('emailadmin.bo');
3489                        $emailadmin_profile = $boemailadmin->getProfileList();
3490                        $emailadmin = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
3491               
3492                        $mail->Host = $emailadmin['smtpServer'];
3493                        $mail->Port = $emailadmin['smtpPort'];
3494                        $mail->From = $sMail;
3495                        $mail->FromName = $sCN;
3496                        $mail->IsHTML(true);
3497                        //Inicializa vari?vel de retorno.
3498                        $returncode=true;               
3499                        // Aqui e enviado o email
3500                        foreach($to_notify as $userid => $statusid)
3501                        {
3502                                $mail->ClearAttachments();
3503                               
3504                                $userid = (int)$userid;
3505
3506                                if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g' || ($sUN == $userid &&  $msg_type != MSG_ALARM))
3507                                    continue;   // dont notify rejected participants or to == send
3508                               
3509                                if($userid != $sUN  ||  $msg_type == MSG_ALARM)
3510                                {
3511                                        print_debug('Msg Type',$msg_type);
3512                                       
3513                                        print_debug('UserID',$userid);
3514
3515                                        $preferences = CreateObject('phpgwapi.preferences',$userid);
3516                                        $part_prefs = $preferences->read_repository();
3517
3518                                        if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event))
3519                                        {
3520                                                continue;
3521                                        }
3522                                        $GLOBALS['phpgw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
3523                                        $details['to-fullname'] = $GLOBALS['phpgw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
3524
3525                                        $to = $preferences->email_address($userid);
3526                                       
3527                                       
3528                                        if( $userid === -2 )
3529                                        {
3530                                                $to = htmlspecialchars_decode( $event['organizer'] );
3531                                        }
3532                                       
3533                                        if (empty($to) || $to[0] == '@' || $to[0] == '$')       // we have no valid email-address
3534                                        {
3535                                                //echo "<p>bocalendar::send_update: Empty email adress for user '".$details['to-fullname']."' ==> ignored !!!</p>\n";
3536                                                continue;
3537                                        }
3538                                        print_debug('Email being sent to',$to);
3539
3540                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
3541                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
3542                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
3543
3544                                        $GLOBALS['phpgw']->datetime->tz_offset = ((60 * 60) * (int)$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']);
3545
3546                                        if($old_starttime)
3547                                        {
3548                                                $details['olddate'] = $GLOBALS['phpgw']->common->show_date($old_starttime);
3549                                        }
3550                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3551                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3552                                       
3553                                       
3554                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3555                                       
3556                                        switch($part_prefs['calendar']['update_format'])
3557                                        {
3558                                                case  'extended':
3559                                                        //$body .= "\n\n".lang('Event Details follow').":\n";
3560                                                        $body = '';
3561                                                        $body .= "<br>".lang('Event Details follow')." :: ";
3562                                                        foreach($event_arr as $key => $val)
3563                                                        {
3564                                                                // titulo
3565                                                                if($key =='title')
3566                                                                {
3567                                                                        $var1 = $val['field'];
3568                                                                        $vardata1 = $details[$key];
3569                                                                }
3570                                                                //descricao
3571                                                                if($key =='description')
3572                                                                {
3573                                                                        $var2 = $val['field'];
3574                                                                        $vardata2 = $details[$key];
3575                                                                }
3576                                                                //dt inicio
3577                                                                if($key =='startdate')
3578                                                                {
3579                                                                        switch(trim($part_prefs['common']['dateformat']))
3580                                                                        {
3581                                                                               
3582                                                                                case ($part_prefs['common']['dateformat'] === "m/d/Y" || $part_prefs['common']['dateformat'] === "m-d-Y" || $part_prefs['common']['dateformat'] === "m.d.Y"):
3583                                                                                        $var3 = $val['field'];
3584                                                                                        $vardata3 = $details[$key];
3585                                                                                        $newmounth3 = substr($vardata3,0,2);
3586                                                                                        $newday3 = substr($vardata3,3,2);
3587                                                                                        $newyear3 = substr($vardata3,6,4);
3588                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3589                                                                                        break;
3590                                                                                       
3591                                                                                case    ($part_prefs['common']['dateformat'] === "Y/d/m" || $part_prefs['common']['dateformat'] === "Y-d-m" || $part_prefs['common']['dateformat'] === "Y.d.m"):
3592
3593                                                                                        $var3 = $val['field'];
3594                                                                                        $vardata3 = $details[$key];
3595                                                                                        $newyear3 = substr($vardata3,0,4);
3596                                                                                        $newday3 = substr($vardata3,5,2);
3597                                                                                        $newmounth3 = substr($vardata3,8,2);
3598                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3599                                                                                        break;
3600
3601                                                                                case ($part_prefs['common']['dateformat'] === "Y/m/d" || $part_prefs['common']['dateformat'] === "Y-m-d" || $part_prefs['common']['dateformat'] === "Y.m.d"):
3602
3603                                                                                        $var3 = $val['field'];
3604                                                                                        $vardata3 = $details[$key];
3605                                                                                        $newyear3 = substr($vardata3,0,4);
3606                                                                                        $newmounth3 = substr($vardata3,5,2);
3607                                                                                        $newday3 = substr($vardata3,8,2);
3608                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3609                                                                                        break;
3610
3611                                                                                case ($part_prefs['common']['dateformat'] === "d/m/Y" || $part_prefs['common']['dateformat'] === "d-m-Y" || $part_prefs['common']['dateformat'] === "d.m.Y" || $part_prefs['common']['dateformat'] === "d-M-Y"):
3612                                                                               
3613                                                                                        $var3 = $val['field'];
3614                                                                                        $vardata3 = $details[$key];
3615                                                                                        $newday3 = substr($vardata3,0,2);
3616                                                                                        $newmounth3 = substr($vardata3,3,2);
3617                                                                                        $newyear3 = substr($vardata3,6,4);
3618                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3619                                                                                        break;
3620                                                                       
3621                                                                        }
3622                                                                       
3623                                                                }
3624                                                                //dt final
3625                                                                if($key =='enddate')
3626                                                                {
3627                                                                        $var4 = $val['field'];
3628                                                                        $vardata4 = $details[$key];
3629                                                                }
3630                                                                //localizacao
3631                                                                if($key =='location')
3632                                                                {
3633                                                                        $var8 = $val['field'];
3634                                                                        $vardata8 = $details[$key];
3635                                                                }
3636                                                                //participantes
3637                                                                if($key =='participants')
3638                                                                {
3639                                                                        $var5 = $val['field'];
3640                                                                        foreach($val['data'] as $NewKey => $NewVal)
3641                                                                        {
3642                                                                                //Research inside of ldap ( Pesquisa dentro do ldap )
3643                                                                                $newvalue = $this->so->search_uidNumber($to);
3644                                                                                foreach($newvalue as $tmp)
3645                                                                                {
3646                                                                                        $tmpmail = $tmp['mail'][0];
3647                                                                                        $tmpuid = $tmp['uidnumber'][0];
3648                                                                                        if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
3649                                                                                        {
3650                                                                                                        if($typesend == 3)
3651                                                                                                        {
3652
3653                                                                                                                $lang1 = lang("To See Commitment");
3654                                                                                                                $varbuttom = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id={$event['id']}&date=$newall3' method='POST'>
3655                                                                                                                                                                  <input type='submit' value='$lang1'>
3656                                                                                                                                                                   </form>";
3657                                                                                                                $lang2 = lang("To accept");
3658                                                                                                                $varbuttom1 ="<input type='submit' value='$lang2' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id={$event['id']}&action=3&response=1&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
3659                                                                                                               
3660                                                                                                                $lang6 = lang("Tentative");
3661                                                                                                                $varbuttom5 ="<input type='submit' value='$lang6' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id={$event['id']}&action=2&response=3&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
3662                                                                                                               
3663
3664                                                                                                                $lang3 = lang("To reject");
3665                                                                                                                $varbuttom2 ="<input type='submit' value='$lang3' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id={$event['id']}&action=0&response=2&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
3666                                                                                                               
3667                                                                                                                $lang4 = lang("Alarm");
3668                                                                                                                $varbuttom3 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uialarm.manager method='POST'>
3669                                                                                                                                                                  <input type='submit' value='$lang4'>
3670                                                                                                                                                                  <input type='hidden' name='cal_id' value=$event[id]>
3671                                                                                                                                                                   </form>";
3672                                                                                                                                                                   
3673                                                                                                                $lang5 = lang("Suggest new hour");
3674                                                                                                                $varbuttom4 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id=$event[id]&date=$newall3&type=1' method='POST'>
3675                                                                                                                                                                  <input type='submit' value='$lang5'>
3676                                                                                                                                                                   </form>";
3677                                                                                                        }
3678                                                                                                        else
3679                                                                                                        {
3680                                                                                                                        $varbuttom  = "";
3681                                                                                                                        $varbuttom1 = "";
3682                                                                                                                        $varbuttom2 = "";
3683                                                                                                                        $varbuttom3 = "";
3684                                                                                                                        $varbuttom4 = "";
3685                                                                                                                        $varbuttom5 = "";
3686                                                                                                        }
3687                                                                                        }
3688                                                                                        // It only mounts variavel with the name of the participants of the list ( Monta a variavel somente com o nome dos participantes da lista)
3689                                                                                        if($typesend == 3)
3690                                                                                        {
3691                                                                                                list($tmpvardata5,$tmp2vardata5) = explode("(",$NewVal);
3692                                                                                                $vardata5 = $tmpvardata5."<br>";
3693                                                                                        }
3694                                                                                        else
3695                                                                                        {
3696                                                                                                $vardata5 = $NewVal."<br>";
3697                                                                                        }
3698                                                                               
3699                                                                                }
3700                                                                                $vardata6 .= $vardata5;
3701                                                                                unset($vardata5);
3702                                                                        }
3703                                                                }               
3704                                                        }
3705                                                        //To mount the message as text/html (Para montar a mensagem como text/html - /phpgwapi/inc/class.send.inc.php )
3706                                                        $content_type = "text/html";
3707                                                        //It mounts the body of the message (Monta o corpo da mensagem)
3708                                                       
3709                                                        // A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
3710                                                        if(!PHPGW_APP_TPL)
3711                                                         define ("PHPGW_APP_TPL",PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3712                                                       
3713                                                                $body = CreateObject('phpgwapi.Template',PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3714                                                        $body->set_file(Array('calendar' => 'body_email.tpl'));
3715                                                        $body->set_block('calendar','list');
3716                                                        $var = Array(
3717                                                                'script'                        => $script,
3718                                                                'subject'                       => $body1,
3719                                                                'var1'                          => $var1,
3720                                                                'vardata1'                      => $vardata1,
3721                                                                'var2'                          => $var2,
3722                                                                'vardata2'                      => $vardata2,
3723                                                                'var3'                          => $var3,
3724                                                                'vardata3'                      => $vardata3,
3725                                                                'var4'                          => $var4,
3726                                                                'vardata4'                      => $vardata4,
3727                                                                'var5'                          => $var5,
3728                                                                'vardata6'                      => $vardata6,
3729                                                                'var8'                          => $var8,
3730                                                                'vardata8'                      => $vardata8,
3731                                                                'varbuttom'                     => $varbuttom,
3732                                                                'varbuttom1'            => $varbuttom1,
3733                                                                'varbuttom2'            => $varbuttom2,
3734                                                                'varbuttom3'            => $varbuttom3,
3735                                                                'varbuttom4'            => $varbuttom4,
3736                                                                'varbuttom5'            => $varbuttom5
3737                                                        );
3738                                                        $body->set_var($var);
3739                                                        $tmpbody = $body->fp('out','list');
3740                                                                                                               
3741                                                        break;
3742
3743                                                case 'ical':
3744                                                        $content_type = "calendar; method=$method; name=calendar.ics";
3745/*                                                      if ($body != '')
3746                                                        {
3747                                                                $boundary = '----Message-Boundary';
3748                                                                $body .= "\n\n\n$boundary\nContent-type: text/$content_type\n".
3749                                                                        "Content-Disposition: inline\nContent-transfer-encoding: 7BIT\n\n";
3750                                                                $content_type = '';
3751                                                        }
3752*/
3753                                                        $body = ExecMethod('calendar.boicalendar.export',array(
3754                                                                'l_event_id'  => $event['id'],
3755                                                                'method'      => $method,
3756                                                                'chunk_split' => False
3757                                                        ));
3758                                                        break;
3759                                        }
3760                                       
3761                                        $mail->AddAddress($to);
3762                                        $mail->Body = $tmpbody;     
3763                                        $mail->From = $sMail;
3764                                        $mail->FromName = $sCN;
3765                                        $mail->Sender = $mail->From;
3766                                        $mail->SenderName = $mail->FromName;
3767                                        $mail->Subject = $subject;
3768                                        unset($vardata5);
3769                                        unset($vardata6);
3770                                       
3771                                        // Envia aviso ao participante.
3772                                        if(!$mail->Send()) {                           
3773                                                $returncode = false;
3774                                                $errorInfo['participants'] = $mail->ErrorInfo;
3775                        }
3776
3777                                        $mail->ClearAddresses();   
3778
3779                                }
3780                            }
3781
3782                        if(!is_object($this->ex_participants))
3783                        {
3784                            include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
3785                            $objexP = new exParticipants();
3786                            $objexP->setParticipantsBySerializable($this->ex_participants);
3787                                }
3788                                else
3789                            $objexP = $this->ex_participants;
3790
3791                       
3792                        if($msg_type === MSG_ADDED && count($this->extAdded) > 0)
3793                               $extMails = $this->extAdded; 
3794                        else if($msg_type === MSG_DELETED && count($this->extDeleted) > 0)
3795                                $extMails = $this->extDeleted; 
3796                        else
3797                            $extMails = array_diff($objexP->getParticipantsMailsArray(), $this->alreadyExtNotifieds);
3798                               
3799                        if(count($extMails) > 0){
3800                                $mail->ClearAllRecipients();
3801                             
3802                                $to = array();
3803                                if(!$subject) {
3804                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3805                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3806                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3807                                }
3808                               
3809                                foreach($extMails as $index => $ex_participant){
3810                                        $ex_participant = trim($ex_participant);
3811                                        $ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
3812                                                if($ex_participant)
3813                                                        $to[] = $ex_participant;
3814                                }               
3815                               
3816                                foreach($to as $i => $to_array)
3817                                        $mail->AddAddress($to_array);
3818                               
3819                                $_body = explode("<hr size='1' width='100%'>",$tmpbody);
3820                                $tmpbody = $_body[0] ? $_body[0] : $subject ;
3821                                $tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($objexP->getParticipantsMailsString());
3822                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[description]."<br>";
3823                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
3824                                $tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
3825                                .lang("This message was sent by server. You must send a message to sender to confirm this event")."<br>"
3826                                .lang("This is an external event. Even if it added to your expresso its can be changed any time at all")."</font><br>";
3827                               
3828                                if ($GLOBALS['bocalendar']->so->cal->event[start][month] > 10)
3829                                        $event_month=$GLOBALS['bocalendar']->so->cal->event[start][month];
3830                                else
3831                                        $event_month="0".$GLOBALS['bocalendar']->so->cal->event[start][month];
3832                                //attach extern vcalendar/icalendar (ics)                       
3833                                // define('context','$GLOBALS.bocalendar.so.cal.event');
3834                               
3835                                $evt = $GLOBALS['bocalendar']->so->cal->event;
3836                                                                 
3837                                /*
3838                                 * Cria Arqvuio ICS
3839                                 */
3840                                require_once dirname(__FILE__).'/../../services/class.servicelocator.php';
3841                                $icalService = ServiceLocator::getService('ical');
3842
3843                                if($msg_type == MSG_DELETED)
3844                                {
3845                                        $icalService->createICal(strtoupper($method));
3846                                        $icalService->addEvent(
3847                                            $old_event['start']['year'].'-'.$old_event['start']['month'].'-'.$old_event['start']['mday'].' '.$old_event['start']['hour'].':'.$old_event['start']['min'].':00',
3848                                            $old_event['end']['year'].'-'.$old_event['end']['month'].'-'.$old_event['end']['mday'].' '.$old_event['end']['hour'].':'.$old_event['end']['min'].':00',
3849                                            array($sMail => array('CN'=> $sCN)),
3850                                            $old_event['title'],
3851                                            $old_event['description'],
3852                                            $old_event['location'],
3853                                            false,
3854                                            false,
3855                                            false,
3856                                            $old_event['uid']
3857                                            );
3858                                }
3859                                else
3860                                {
3861                                        $attendee = array();
3862                                        foreach($to as $value)
3863                                            $attendee[$value] = array('RSVP' => 'TRUE','ROLE' => 'REQ-PARTICIPANT');
3864
3865                                        $attendee =  array_merge($attendee,$this->getCalendarParticipantsArray($evt['id']));
3866                                        $icalService->createICal(strtoupper($method));
3867                                        $icalService->addEvent(
3868                                            $evt['start']['year'].'-'.$evt['start']['month'].'-'.$evt['start']['mday'].' '.$evt['start']['hour'].':'.$evt['start']['min'].':00',
3869                                            $evt['end']['year'].'-'.$evt['end']['month'].'-'.$evt['end']['mday'].' '.$evt['end']['hour'].':'.$evt['end']['min'].':00',
3870                                            array($sMail => array('CN'=> $sCN)),
3871                                            $evt['title'],
3872                                            $evt['description'],
3873                                            $evt['location'],
3874                                            $attendee,
3875                                            false,
3876                                            false,
3877                                            $evt['uid']
3878                                            );
3879
3880                                }
3881
3882
3883                                $tmpattach = $icalService->getICal();
3884                                //-------------------------------------------------//
3885                               
3886                                if($tmpattach){                                 
3887                                        $tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
3888                                        srand((double)microtime()*1000000);
3889                                        $random_number = rand(100000000,999999999);
3890                                        $newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
3891                                        $filename = $tempdir . $newfilename;
3892                                        $attach_fd = fopen($filename,"w+");
3893                                        fwrite($attach_fd,$tmpattach);
3894                                        $mail->AddAttachment($filename, "extern.ics", "base64", "text/plain"); // "application/octet-stream"
3895                                        fclose($attach_fd);
3896                                }
3897                                $mail->From = $sMail;
3898                                $mail->FromName = $sCN;
3899                                $mail->Sender = $mail->From;
3900                                $mail->SenderName = $mail->FromName;
3901                                $mail->Subject = lang("External event from Expresso");
3902                                $mail->Body = $tmpbody;
3903                                                                                                                                               
3904                                if(!$mail->Send())
3905                                {
3906                                        $returncode=false;
3907                                        $errorInfo['ex_participants'] = $mail->ErrorInfo;
3908                                }
3909                                else
3910                                {
3911                                        $returncode=true;
3912                                }
3913                        }
3914
3915
3916                        if((is_int($this->user) && $this->user != $temp_user['account_id']) ||
3917                                (is_string($this->user) && $this->user != $temp_user['account_lid']))
3918                        {
3919                                $GLOBALS['phpgw_info']['user'] = $temp_user;
3920                        }       
3921
3922                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $temp_tz_offset;
3923                        $GLBOALS['phpgw']->datetime->tz_offset = ((60 * 60) * $temp_tz_offset);
3924                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $temp_timeformat;
3925                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
3926                       
3927                        // Notifica por email o criador do compromisso, com as poss?veis falhas.                                               
3928                        if($errorInfo) {
3929                                $tmpbody = "<font color='red'>".lang("The following commitment had problems for DELIVERING the NOTIFICATION messages.").".</font><br>";
3930                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
3931                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";                         
3932                                $tmpbody.= "<br><u>".lang("Failed to delivery")."</u><br>";
3933                                $failed = false;                               
3934                                if(strstr($errorInfo['participants'],"recipients_failed")){
3935                                        $failed = explode("recipients_failed",$errorInfo['participants']);
3936                                        $tmpbody.= lang("to").": ".$failed[1];
3937                                }
3938                                if(strstr($errorInfo['ex_participants'],"recipients_failed")){
3939                                        $failed = explode("recipients_failed",$errorInfo['ex_participants']);
3940                                        $tmpbody.= lang("to").": ".$failed[1];
3941                                }                       
3942                                if(!$failed) {
3943                                        $tmpbody.= lang("Description").":<br>";
3944                                        $tmpbody.= $errorInfo['participants'];
3945                                        $tmpbody.= "<br>".$errorInfo['ex_participants'];
3946                                }
3947                                $tmpbody.= "<br>".lang("Subject").": ".$subject;
3948                                // Reinicializa o objeto, devido ao erro anterior na entrega.
3949                               
3950                                $mail = new PHPMailer();
3951                                $mail->IsSMTP();
3952                                $mail->Host = $emailadmin['smtpServer'];
3953                                $mail->Port = $emailadmin['smtpPort'];
3954                                $mail->From = $sMail;
3955                                $mail->FromName = $sCN;
3956                                $mail->Sender = $mail->From;
3957                                $mail->SenderName = $mail->FromName;
3958                                $mail->IsHTML(True);
3959                                $mail->Subject = lang("calendar event")." - ".lang("email notification");                                                       
3960                                $mail->Body = $tmpbody;                                 
3961                                $mail->AddAddress($sMail);
3962                                if(!$mail->Send())                     
3963                                        $returncode = false;
3964                                else
3965                                        $returncode =  true;
3966                        }
3967                        return $returncode;
3968                }
3969               
3970               
3971               
3972                /**
3973                 * @license http://www.gnu.org/copyleft/gpl.html GPL
3974                 * @author Prognus Software Livre (http://www.prognus.com.br)
3975                 */
3976                function send_suggestion_external_owner($cal_id, $uid, $to, $time_suggest, $array_data_inicio, $array_data_final, $title, $description, $location, $ex_participants,$user = false)
3977                {
3978
3979                    if($cal_id)
3980                        $event =  $this->so->read_entry($cal_id);
3981                    else
3982                    {
3983                        $event = $this->restore_from_appsession();
3984                        $this->so->add_entry( $event , false);
3985                    }
3986                   
3987                    $this->so->cal->set_status($event['id'],$user,2);
3988
3989
3990                    if($user && $user != $GLOBALS['phpgw_info']['user']['account_id'])
3991                    {
3992                        $ldap = $this->getLdap();
3993                        $justthese = array("mail","cn");
3994                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3995                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3996                        $entry = ldap_get_entries($ldap, $search);
3997                        $ownerMail = $entry[0]['mail'][0];
3998                        $ownerCN = $entry[0]['cn'][0];
3999                     }
4000                     else
4001                     {
4002                        $ownerMail = $GLOBALS['phpgw_info']['user']['email'];
4003                        $ownerCN = $GLOBALS['phpgw_info']['user']['fullname'];
4004                     }
4005                     
4006                    require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
4007                    $icalService = ServiceLocator::getService('ical');
4008                    $dia_inicio = $array_data_inicio[0];
4009                    $mes_inicio = $array_data_inicio[1];
4010                    $ano_inicio = $array_data_inicio[2];
4011                    $hora_inicio = $time_suggest['hora_inicio'];
4012                    $minuto_inicio = $time_suggest['minuto_inicio'];
4013                    $dia_final = $array_data_final[0];
4014                    $mes_final = $array_data_final[1];
4015                    $ano_final = $array_data_final[2];
4016                    $hora_final = $time_suggest['hora_final'];
4017                    $minuto_final = $time_suggest['minuto_final'];
4018
4019                    $dtStart = $array_data_inicio[2] . '/' .
4020                               $array_data_inicio[1] . '/' .
4021                               $array_data_inicio[0] . ' ' .
4022                               $time_suggest['hora_inicio'] . ':' .
4023                               $time_suggest['minuto_inicio'] . ':00';
4024
4025                    $dtEnd = $array_data_final[2] . '/' .
4026                             $array_data_final[1] . '/' .
4027                             $array_data_final[0] . ' ' .
4028                             $time_suggest['hora_final'] . ':' .
4029                             $time_suggest['minuto_final'] . ':00';
4030
4031                    $icalService->createICal('REPLY');
4032
4033                    $other = array( 'X-MICROSOFT-CDO-IMPORTANCE' => '1',
4034                                    'X-EXPRESSO-SUGGESTION-HOUR' => '1',
4035                                    'CLASS' => 'PUBLIC',
4036                                    'PRIORITY' => '5',
4037                                    'SEQIENCE' => '0',
4038                                    'TRANSP' => 'OPAQUE');
4039
4040                    /* Corpo do email */
4041                    $tmpbody2 = lang("The sender suggested a new hours for the appointment");
4042                    $tmpbody2.= " <br /> <b>" . lang("Title") . ":</b> $title";
4043                    $tmpbody2.= " <br /> <b>" . lang("Details") . ":</b> <br /> <br /> <b>" . lang("Start") . "  </b>" . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4044                    $tmpbody2.= " <br /> <b>" . lang("End") . " </b>" . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "<br><br><br><br>";
4045                    $tmpbody = lang("The sender suggested a new hours for the appointment");
4046                    $tmpbody.= " \r\n " . lang("Title") . ": $title";
4047                    $tmpbody.= " \r\n " . lang("Suggestion") . ": \r\n \r\n " . lang("Start") . "  " . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4048                    $tmpbody.= " \r\n " . lang("End") . " " . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "";
4049
4050                    $icalService->addEvent($dtStart,
4051                            $dtEnd,
4052                            $to,
4053                            $title,
4054                            utf8_encode($tmpbody),
4055                            $location,
4056                            array($ownerMail => array('CN' => $ownerCN, 'PARTSTAT' => 'TENTATIVE')),
4057                            $other,
4058                            false,
4059                            $uid
4060                    );
4061                   
4062                    $tmpattach =  $icalService->getICal();                   
4063                   
4064                    $mailService = ServiceLocator::getService('mail');
4065                    $mailService->addStringAttachment($tmpattach, 'suggestion.ics', 'application/ics');
4066                    $mailService->addStringAttachment($tmpattach, 'vcalendar.ics', 'text/calendar; charset=utf-8; method=REPLY;', '7bit', 'inline');
4067                    $mailService->sendMail($to, $ownerMail, $title, $tmpbody2);
4068                     
4069                    return $event['id'];                   
4070                }               
4071               
4072                function send_alarm($alarm)
4073                {
4074                        //echo "<p>bocalendar::send_alarm("; print_r($alarm); echo ")</p>\n";
4075                       
4076                        $GLOBALS['phpgw_info']['user']['account_id'] = $this->owner = $alarm['owner'];
4077
4078                        if (!$alarm['enabled'] || !$alarm['owner'] || !$alarm['cal_id'] || !($event = $this->so->read_entry($alarm['cal_id'])))
4079                        {
4080                                return False;   // event not found
4081                        }
4082                        if ($alarm['all'])
4083                        {
4084                                $to_notify = $event['participants'];
4085                        }
4086                        elseif ($this->check_perms(PHPGW_ACL_READ,$event))      // checks agains $this->owner set to $alarm[owner]
4087                        {
4088                                $to_notify[$alarm['owner']] = 'A';
4089                        }
4090                        else
4091                        {
4092                                return False;   // no rights
4093                        }
4094                        return $this->send_update(MSG_ALARM,$to_notify,$event,False,$alarm['owner']);
4095                }
4096
4097                function get_alarms($event_id)
4098                {
4099                        return $this->so->get_alarm($event_id);
4100                }
4101
4102                function alarm_today($event,$today,$starttime)
4103                {
4104                        $found = False;
4105                        @reset($event['alarm']);
4106                        $starttime_hi = $GLOBALS['phpgw']->common->show_date($starttime,'Hi');
4107                        $t_appt['month'] =$GLOBALS['phpgw']->common->show_date($today,'m');
4108                        $t_appt['mday'] = $GLOBALS['phpgw']->common->show_date($today,'d');
4109                        $t_appt['year'] = $GLOBALS['phpgw']->common->show_date($today,'Y');
4110                        $t_appt['hour'] = $GLOBALS['phpgw']->common->show_date($starttime,'H');
4111                        $t_appt['min']  = $GLOBALS['phpgw']->common->show_date($starttime,'i');
4112                        $t_appt['sec']  = 0;
4113                        $t_time = $this->maketime($t_appt) - $GLOBALS['phpgw']->datetime->tz_offset;
4114                        $y_time = $t_time - 86400;
4115                        $tt_time = $t_time + 86399;
4116                        print_debug('T_TIME',$t_time.' : '.$GLOBALS['phpgw']->common->show_date($t_time));
4117                        print_debug('Y_TIME',$y_time.' : '.$GLOBALS['phpgw']->common->show_date($y_time));
4118                        print_debug('TT_TIME',$tt_time.' : '.$GLOBALS['phpgw']->common->show_date($tt_time));
4119                        while(list($key,$alarm) = each($event['alarm']))
4120                        {
4121                                if($alarm['enabled'])
4122                                {
4123                                        print_debug('TIME',$alarm['time'].' : '.$GLOBALS['phpgw']->common->show_date($alarm['time']).' ('.$event['id'].')');
4124                                        if($event['recur_type'] != MCAL_RECUR_NONE)   /* Recurring Event */
4125                                        {
4126                                                print_debug('Recurring Event');
4127                                                if($alarm['time'] > $y_time && $GLOBALS['phpgw']->common->show_date($alarm['time'],'Hi') < $starttime_hi && $alarm['time'] < $t_time)
4128                                                {
4129                                                        $found = True;
4130                                                }
4131                                        }
4132                                        elseif($alarm['time'] > $y_time && $alarm['time'] < $t_time)
4133                                        {
4134                                                $found = True;
4135                                        }
4136                                }
4137                        }
4138                        print_debug('Found',$found);
4139                        return $found;
4140                }
4141
4142                function prepare_recipients(&$new_event,$old_event,$userSend)
4143                {
4144                        //Verifica se ouve alguem deletado
4145                        foreach($old_event['participants'] as $key => $value)
4146                           if(!array_key_exists($key, $new_event['participants']))
4147                                {
4148                               $this->deleted[$key] = $value;
4149                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4150                                }
4151                        //Verifica se ouve alguem adicionado
4152                        foreach($new_event['participants'] as $key => $value)
4153                           if(!array_key_exists($key, $old_event['participants']))
4154                                {
4155                               $this->added[$key] = $value;
4156                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4157                        }
4158                       
4159                        //Verifica se ouve alguem modificado
4160                        foreach($new_event['participants'] as $key => $value)
4161                        {
4162                            if(array_key_exists($key, $old_event['participants']))                       
4163                                {
4164                                if($old_event['participants'][$key] != $value)
4165                                {
4166                                    $this->modified[$key] = $value; 
4167                                    $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4168                                }
4169                                }
4170                        }
4171                         //Verificando alterações em usuarios externos
4172                         include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
4173                         $extOld = new exParticipants();
4174                         $extNew = new exParticipants();
4175                         
4176                         $extOld->setParticipantsBySerializable($old_event['ex_participants']);
4177                         $extNew->setParticipantsBySerializable($new_event['ex_participants']);
4178                       
4179                         $oldArray = $extOld->getParticipantsMailsArray();
4180                         $newArray = $extNew->getParticipantsMailsArray();
4181                         
4182                        //Verifica se ouve alguem deletado
4183                        $this->extDeleted = array_diff($oldArray, $newArray);
4184                       
4185                        //Verifica se ouve alguem adicionado
4186                        $this->extAdded = array_diff($newArray, $oldArray);
4187                       
4188                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extDeleted);
4189                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extAdded);
4190                        //---------------------------------------------------------------------------------//
4191                       
4192                        if(count($this->added) > 0 || count($this->extAdded))
4193                                $this->send_update(MSG_ADDED,$this->added,'',$new_event,$userSend);
4194                       
4195                        if(count($this->modified) > 0)
4196                                $this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event,$userSend);
4197                       
4198                        if(count($this->deleted) > 0 || count($this->extDeleted))
4199                                $this->send_update(MSG_DELETED,$this->deleted,$old_event,false,$userSend);
4200                                               
4201                }
4202
4203                function remove_doubles_in_cache($firstday,$lastday)
4204                {
4205                        $already_moved = Array();
4206                        for($v=$firstday;$v<=$lastday;++$v)
4207                        {
4208                                if (!$this->cached_events[$v])
4209                                {
4210                                        continue;
4211                                }
4212                                $cached = $this->cached_events[$v];
4213                                $this->cached_events[$v] = array();
4214                                while (list($g,$event) = each($cached))
4215                                {
4216                                        $end = date('Ymd',$this->maketime($event['end']));
4217                                        print_debug('EVENT',_debug_array($event,False));
4218                                        print_debug('start',$start);
4219                                        print_debug('v',$v);
4220
4221                                        if (!isset($already_moved[$event['id']]) || $event['recur_type'] && $v > $end)
4222                                        {
4223                                                $this->cached_events[$v][] = $event;
4224                                                $already_moved[$event['id']] = 1;
4225                                                print_debug('Event moved');
4226                                        }
4227                                }
4228                        }
4229                }
4230
4231                function get_dirty_entries($lastmod=-1)
4232                {
4233                        $events = false;
4234                        $event_ids = $this->so->cal->list_dirty_events($lastmod);
4235                        if(is_array($event_ids))
4236                        {
4237                                foreach($event_ids as $key => $id)
4238                                {
4239                                        $events[$id] = $this->so->cal->fetch_event($id);
4240                                }
4241                        }
4242                        unset($event_ids);
4243
4244                        $rep_event_ids = $this->so->cal->list_dirty_events($lastmod,$true);
4245                        if(is_array($rep_event_ids))
4246                        {
4247                                foreach($rep_event_ids as $key => $id)
4248                                {
4249                                        $events[$id] = $this->so->cal->fetch_event($id);
4250                                }
4251                        }
4252                        unset($rep_event_ids);
4253
4254                        return $events;
4255                }
4256
4257                function _debug_array($data)
4258                {
4259                        echo '<br>UI:';
4260                        _debug_array($data);
4261                }
4262
4263                /*!
4264                @function rejected_no_show
4265                @abstract checks if event is rejected from user and he's not the owner and dont want rejected
4266                @param $event to check
4267                @returns True if event should not be shown
4268                */
4269                function rejected_no_show($event)
4270                {
4271                        $ret = !$this->prefs['calendar']['show_rejected'] &&
4272                                $event['owner'] != $this->owner &&
4273                                $event['participants'][$this->owner] == 'R';
4274                        //echo "<p>rejected_no_show($event[title])='$ret': user=$this->owner, event-owner=$event[owner], status='".$event['participants'][$this->owner]."', show_rejected='".$this->prefs['calendar']['show_rejected']."'</p>\n";
4275                        return $ret;
4276                }
4277
4278                /* This is called only by list_cals().  It was moved here to remove fatal error in php5 beta4 */
4279                function list_cals_add($id,&$users,&$groups)
4280                {
4281                        $name = $GLOBALS['phpgw']->common->grab_owner_name($id);
4282                        if (($type = $GLOBALS['phpgw']->accounts->get_type($id)) == 'g')
4283                        {
4284                                $arr = &$groups;
4285                        }
4286                        else
4287                        {
4288                                $arr = &$users;
4289                        }
4290                        $arr[$name] = Array(
4291                                'grantor' => $id,
4292                                'value'   => ($type == 'g' ? 'g_' : '') . $id,
4293                                'name'    => $name
4294                        );
4295                }
4296
4297                /*!
4298                @function list_cals
4299                @abstract generate list of user- / group-calendars for the selectbox in the header
4300                @returns alphabeticaly sorted array with groups first and then users
4301                */
4302                function list_cals()
4303                {
4304                        $users = $groups = array();
4305                        foreach($this->grants as $id => $rights)
4306                        {
4307                                $this->list_cals_add($id,$users,$groups);
4308                        }
4309                       
4310                        //by JakJr, melhora de performance na abertura da agenda
4311                        /*if ($memberships = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']))
4312                        {
4313                                foreach($memberships as $group_info)
4314                                {
4315                                        $this->list_cals_add($group_info['account_id'],$users,$groups);
4316
4317                                        if ($account_perms = $GLOBALS['phpgw']->acl->get_ids_for_location($group_info['account_id'],PHPGW_ACL_READ,'calendar'))
4318                                        {
4319                                                foreach($account_perms as $id)
4320                                                {
4321                                                        $this->list_cals_add($id,$users,$groups);
4322                                                }
4323                                        }
4324                                }
4325                        }*/
4326                        uksort($users,'strnatcasecmp');
4327                        uksort($groups,'strnatcasecmp');
4328
4329                        return $users + $groups;        // users first and then groups, both alphabeticaly
4330                }
4331
4332          function translate($key,$vars=false, $not_found='*' )
4333          {
4334            if ($this->async)
4335              return $GLOBALS['phpgw']->translation->translate_async($key, $vars);
4336            return lang($key, $vars);
4337          }
4338
4339                /*!
4340                @function event2array
4341                @abstract create array with name, translated name and readable content of each attributes of an event
4342                @syntax event2array($event,$sep='<br>')
4343                @param $event event to use
4344                @returns array of attributes with fieldname as key and array with the 'field'=translated name \
4345                        'data' = readable content (for participants this is an array !)
4346                */
4347                function event2array($event)
4348                {
4349                       
4350                       
4351                  $var['title'] = Array(
4352                                'field'         => $this->translate('Title'),
4353                                'data'          => $event['title']
4354                        );
4355
4356                        // Some browser add a \n when its entered in the database. Not a big deal
4357                        // this will be printed even though its not needed.
4358                        $var['description'] = Array(
4359                                'field' => $this->translate('Description'),
4360                                'data'  => $event['description']
4361                        );
4362
4363                        $var['ex_participants'] = Array(
4364                                'field' => $this->translate('External Participants'),
4365                                'data'  => $event['ex_participants']
4366                        );
4367                       
4368                        $cats = Array();
4369                        $this->cat->categories($this->bo->owner,'calendar');
4370                        if(strpos($event['category'],','))
4371                        {
4372                                $cats = explode(',',$event['category']);
4373                        }
4374                        else
4375                        {
4376                                $cats[] = $event['category'];
4377                        }
4378                        foreach($cats as $cat_id)
4379                        {
4380                                list($cat) = $this->cat->return_single($cat_id);
4381                                $cat_string[] = $cat['name'];
4382                        }
4383                        $var['category'] = Array(
4384                                'field' => $this->translate('Category'),
4385                                'data'  => implode(', ',$cat_string)
4386                        );
4387
4388                        $var['location'] = Array(
4389                                'field' => $this->translate('Location'),
4390                                'data'  => $event['location']
4391                        );
4392
4393                        $var['startdate'] = Array(
4394                                'field' => $this->translate('Start Date/Time'),
4395                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset),
4396                        );
4397
4398                        $var['enddate'] = Array(
4399                                'field' => $this->translate('End Date/Time'),
4400                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset)
4401                        );
4402
4403                        $pri = Array(
4404                                1       => lang('Low'),
4405                                2       => lang('Normal'),
4406                                3       => lang('High')
4407                        );
4408                        $var['priority'] = Array(
4409                                'field' => lang('Priority'),
4410                                'data'  => $pri[$event['priority']]
4411                        );
4412
4413                        $owner = $event['owner'];
4414
4415                        $owner_name = ( $owner === -2 )? $event['organizer'] : $GLOBALS['phpgw']->common->grab_owner_name( $owner );
4416
4417                        $var['owner'] = Array(
4418                                'field' => lang('Created By'),
4419                                'data'  => $owner_name
4420                        );
4421
4422                        $var['updated'] = Array(
4423                                'field' => lang('Updated'),
4424                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['modtime']) - $GLOBALS['phpgw']->datetime->tz_offset)
4425                        );
4426
4427                        if($event['public']){
4428                                $type = lang('Public');
4429                        }else if (!$event['public'] && $event['type'] == 'E'){
4430                                $type = lang('Restrict');
4431                        }else{
4432                                $type = lang('Private');
4433                        }
4434
4435                        $var['access'] = Array(
4436                                'field' => lang('Access'),
4437                                'data'  => $type
4438                        );
4439
4440                        if(@isset($event['groups'][0]))
4441                        {
4442                                $cal_grps = '';
4443                $event_groups_count = count($event['groups']);
4444                                for($i=0;$i<$event_groups_count;++$i)
4445                                {
4446                                        if($GLOBALS['phpgw']->accounts->exists($event['groups'][$i]))
4447                                        {
4448                                                $cal_grps .= ($i>0?'<br>':'').$GLOBALS['phpgw']->accounts->id2name($event['groups'][$i]);
4449                                        }
4450                                }
4451
4452                                $var['groups'] = Array(
4453                                        'field' => lang('Groups'),
4454                                        'data'  => $cal_grps
4455                                );
4456                        }
4457
4458                        $participants = array();
4459                        foreach($event['participants'] as $user => $short_status)
4460                        {
4461                                if($GLOBALS['phpgw']->accounts->exists($user))
4462                                {
4463                                        $participants[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user).' ('.$this->get_long_status($short_status).')';
4464                                }
4465                        }
4466                        $var['participants'] = Array(
4467                                'field' => $this->translate('Participants'),
4468                                'data'  => $participants
4469                        );
4470
4471                        // Repeated Events
4472                        if($event['recur_type'] != MCAL_RECUR_NONE)
4473                        {
4474                                $str = lang($this->rpt_type[$event['recur_type']]);
4475
4476                                $str_extra = array();
4477                                if ($event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['year'] != 0)
4478                                {
4479                                        $recur_end = $this->maketime($event['recur_enddate']);
4480                                        if($recur_end != 0)
4481                                        {
4482                                                $recur_end -= $GLOBALS['phpgw']->datetime->tz_offset;
4483                                                $str_extra[] = lang('ends').': '.lang($GLOBALS['phpgw']->common->show_date($recur_end,'l')).', '.$this->long_date($recur_end).' ';
4484                                        }
4485                                }
4486                                // only weekly uses the recur-data (days) !!!
4487                                if($event['recur_type'] == MCAL_RECUR_WEEKLY)
4488                                {
4489                                        $repeat_days = array();
4490                                        foreach ($this->rpt_day as $mcal_mask => $dayname)
4491                                        {
4492                                                if ($event['recur_data'] & $mcal_mask)
4493                                                {
4494                                                        $repeat_days[] = lang($dayname);
4495                                                }
4496                                        }
4497                                        if(count($repeat_days))
4498                                        {
4499                                                $str_extra[] = lang('days repeated').': '.implode(', ',$repeat_days);
4500                                        }
4501                                }
4502                                if($event['recur_interval'] != 0)
4503                                {
4504                                        $str_extra[] = lang('Interval').': '.$event['recur_interval'];
4505                                }
4506
4507                                if(count($str_extra))
4508                                {
4509                                        $str .= ' ('.implode(', ',$str_extra).')';
4510                                }
4511
4512                                $var['recure_type'] = Array(
4513                                        'field' => lang('Repetition'),
4514                                        'data'  => $str,
4515                                );
4516                        }
4517
4518                        if (!isset($this->fields))
4519                        {
4520                                $this->custom_fields = CreateObject('calendar.bocustom_fields');
4521                                $this->fields = &$this->custom_fields->fields;
4522                                $this->stock_fields = &$this->custom_fields->stock_fields;
4523                        }
4524                        foreach($this->fields as $field => $data)
4525                        {
4526                                if (!$data['disabled'])
4527                                {
4528                                        if (isset($var[$field]))
4529                                        {
4530                                                $sorted[$field] = $var[$field];
4531                                        }
4532                                        elseif (!isset($this->stock_fields[$field]) && strlen($event[$field]))  // Custom field
4533                                        {
4534                                                $lang = lang($name = substr($field,1));
4535                                                $sorted[$field] = array(
4536                                                        'field' => $lang == $name.'*' ? $name : $lang,
4537                                                        'data'  => $event[$field]
4538                                                );
4539                                        }
4540                                }
4541                                unset($var[$field]);
4542                        }
4543                        foreach($var as $name => $v)
4544                        {
4545                                $sorted[$name] = $v;
4546
4547                        }
4548                        return $sorted;
4549                }
4550
4551                /*!
4552                @function check_set_default_prefs
4553                @abstract sets the default prefs, if they are not already set (on a per pref. basis)
4554                @note It sets a flag in the app-session-data to be called only once per session
4555                */
4556                function check_set_default_prefs()
4557                {
4558                        if (($set = $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar')))
4559                        {
4560                                return;
4561                        }
4562                        $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar','set');
4563
4564                        $default_prefs = $GLOBALS['phpgw']->preferences->default['calendar'];
4565
4566                        $subject = $this->translate('Calendar Event') . ' - $$action$$: $$startdate$$ $$title$$'."\n";
4567                        $defaults = array(
4568                                'defaultcalendar' => 'week',
4569                                'mainscreen_showevents' => '0',
4570                                'summary'         => 'no',
4571                                'receive_updates' => 'no',
4572                                'update_format'   => 'extended',        // leave it to extended for now, as iCal kills the message-body
4573                                'notifyAdded'     => $subject . $this->translate ('You have a meeting scheduled for %1',array('$$startdate$$')),
4574                                'notifyCanceled'  => $subject . $this->translate ('Your meeting scheduled for %1 has been canceled',array('$$startdate$$')),
4575                                'notifyModified'  => $subject . $this->translate ('Your meeting that had been scheduled for %1 has been rescheduled to %2',array('$$olddate$$','$$startdate$$')),
4576                                'notifyResponse'  => $subject . $this->translate ('On %1 %2 %3 your meeting request for %4', array('$$date$$','$$fullname$$','$$action$$','$$startdate$$')),
4577                                'notifyAlarm'     => $this->translate('Alarm for %1 at %2 in %3',array('$$title$$','$$startdate$$','$$location$$')) . "\n" . $this->translate('Here is your requested alarm.'),
4578                                'show_rejected'   => '0',
4579                                'hide_event_conflict'   => '0',
4580                                'display_status'  => '1',
4581                                'weekdaystarts'   => 'Monday',
4582                                'workdaystarts'   => '9',
4583                                'workdayends'     => '17',
4584                                'interval'        => '30',
4585                                'defaultlength'   => '60',
4586                                'planner_start_with_group' => $GLOBALS['phpgw']->accounts->name2id('Default'),
4587                                'planner_intervals_per_day'=> '4',
4588                                'defaultfilter'   => 'all',
4589                                'default_private' => '0',
4590                                'display_minicals'=> '1',
4591                                'print_black_white'=>'0'
4592                        );
4593                        foreach($defaults as $var => $default)
4594                        {
4595                                if (!isset($default_prefs[$var]) || $default_prefs[$var] == '')
4596                                {
4597                                        $GLOBALS['phpgw']->preferences->add('calendar',$var,$default,'default');
4598                                        $need_save = True;
4599                                }
4600                        }
4601                        if ($need_save)
4602                        {
4603                                $prefs = $GLOBALS['phpgw']->preferences->save_repository(False,'default');
4604                                $this->prefs['calendar'] = $prefs['calendar'];
4605                        }
4606                        if ($this->prefs['calendar']['send_updates'] && !isset($this->prefs['calendar']['receive_updates']))
4607                        {
4608                                $this->prefs['calendar']['receive_updates'] = $this->prefs['calendar']['send_updates'];
4609                                $GLOBALS['phpgw']->preferences->add('calendar','receive_updates',$this->prefs['calendar']['send_updates']);
4610                                $GLOBALS['phpgw']->preferences->delete('calendar','send_updates');
4611                                $prefs = $GLOBALS['phpgw']->preferences->save_repository();
4612                        }
4613                }
4614
4615                // return array with all infolog categories (for xmlrpc)
4616                function categories($complete = False)
4617                {
4618                        return $GLOBALS['server']->categories($complete);
4619                }
4620        }
4621?>
Note: See TracBrowser for help on using the repository browser.