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

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

Ticket #3236 - Revisao das Melhorias de performance no codigo do Expresso.

  • 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                        for($i = 0; $i < count($sts); ++$i ){
2873                                if( $sts[i] === "R")
2874                                        unset( $sts[i] );
2875                        }
2876                       
2877                        if( empty( $sts ) )
2878                        {
2879                                $this->so->delete_entry( $cal_id );
2880                                $this->so->expunge();
2881                        }
2882                }
2883
2884                /*!
2885                @function update_requested
2886                @abstract checks if $userid has requested (in $part_prefs) updates for $msg_type
2887                @syntax update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2888                @param $userid numerical user-id
2889                @param $part_prefs preferces of the user $userid
2890                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
2891                @param $old_event Event before the change
2892                @param $new_event Event after the change
2893                @returns 0 = no update requested, > 0 update requested
2894                */
2895                function update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2896                {
2897                        if ($msg_type == MSG_ALARM)
2898                        {
2899                                return True;    // always True for now
2900                        }
2901                        $want_update = 0;
2902
2903                        // the following switch fall-through all cases, as each included the following too
2904                        //
2905                        $msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE;
2906
2907                        switch($ru = $part_prefs['calendar']['receive_updates'])
2908                        {
2909                                case 'responses':
2910                                        if ($msg_is_response)
2911                                        {
2912                                                ++$want_update;
2913                                        }
2914                                case 'modifications':
2915                                        if ($msg_type == MSG_MODIFIED)
2916                                        {
2917                                                ++$want_update;
2918                                        }
2919                                case 'time_change_4h':
2920                                case 'time_change':
2921                                        $diff = max(abs($this->maketime($old_event['start'])-$this->maketime($new_event['start'])),
2922                                                abs($this->maketime($old_event['end'])-$this->maketime($new_event['end'])));
2923                                        $check = $ru == 'time_change_4h' ? 4 * 60 * 60 - 1 : 0;
2924                                        if ($msg_type == MSG_MODIFIED && $diff > $check)
2925                                        {
2926                                                ++$want_update;
2927                                        }
2928                                case 'add_cancel':
2929                                        if ($old_event['owner'] == $userid && $msg_is_response ||
2930                                                $msg_type == MSG_DELETED || $msg_type == MSG_ADDED)
2931                                        {
2932                                                ++$want_update;
2933                                        }
2934                                        break;
2935                                case 'no':
2936                                        break;
2937                        }
2938                        //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";
2939                        return $want_update > 0;
2940                }
2941
2942
2943                function create_vcard($event_arrays , $metodo = 'PUBLISH', $externo = false,$importAccount = false)
2944                {
2945                    if(!$importAccount)
2946                        $importAccount['mail'] = $GLOBALS['phpgw_info']['user']['email'];
2947
2948                    if(!is_array($event_arrays))
2949                                return null;
2950
2951                    $tmpattach="BEGIN:VCALENDAR\r\n"
2952                        ."PRODID:-//Expresso Livre//Calendar//EN\r\n"
2953                        ."VERSION:2.0\r\n"
2954                        ."CALSCALE:GREGORIAN\r\n"
2955                        ."METHOD:".$metodo."\r\n";
2956
2957                    //$offset = ((int)substr(date('O',$GLOBALS['phpgw']->datetime->users_localtime), 0, 3));
2958                   
2959                    //Recupera o offset do cliente com base na diferenca entre o horario do cliente (timezone da preferencia)
2960                    //e o unixtime
2961                    //$offset = ((($GLOBALS['phpgw']->datetime->users_localtime) -  ($GLOBALS['phpgw']->datetime->gmtnow))/60)/60;
2962                   
2963                        $timezone = date('e');
2964
2965                        foreach ($event_arrays as $event_array)
2966                        {
2967                            $sy = $event_array['start']['year'];
2968                            $sm = $event_array['start']['month'];
2969                            $sd = $event_array['start']['mday'];
2970                            $sh = $event_array['start']['hour'];
2971                            $sn = $event_array['start']['min'];
2972                            $dtstart = sprintf("%04d%02d%02dT%02d%02d00", $sy, $sm, $sd, $sh, $sn);
2973
2974                            $ey = $event_array['end']['year'];
2975                            $em = $event_array['end']['month'];
2976                            $ed = $event_array['end']['mday'];
2977                            $eh = $event_array['end']['hour'];
2978                            $en = $event_array['end']['min'];
2979                            $dtend = sprintf("%04d%02d%02dT%02d%02d00", $ey, $em, $ed, $eh, $en);
2980
2981                            // Necessário espaços após quebra-de-linha, na descrição, caso contrário
2982                            // ocorrerá erro ao importar o agendamento no Outlook (erro lunar).
2983                            $description = str_replace("\n","\n ",$event_array['description']);
2984                            $tmpattach.="BEGIN:VEVENT\r\n";
2985                                                       
2986                            if(isset($event_array['organizer']) && $event_array['owner'] != -2)
2987                            {
2988                                $ldap = $this->getLdap(); 
2989                                $justthese = array("mail","cn");
2990                                $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$event_array['owner']."))";
2991                                $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
2992                                $entry = ldap_get_entries($ldap, $search);                                       
2993                                        $organizer = 'ORGANIZER;CN='.$entry[0]['cn'][0].':mailto:'.$entry[0]['mail'][0]."\r\n";
2994                                }   
2995                                else{   
2996                                        $email = explode('&lt;', $event_array['organizer']);
2997                                        $email2 = explode('&gt;', $email[1]);
2998                                $organizer = 'ORGANIZER;CN='.rtrim($email[0]).':mailto:'.$email2[0]."\r\n";
2999                                                        }
3000                                                                 
3001                            if(!$externo)
3002                            {
3003                                $tmpattach.=
3004                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
3005                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
3006                                ."LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3007                                                                .$organizer
3008                                ."UID:".$event_array['uid']."\r\n"
3009                                .$this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3010                                .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3011                                ."DESCRIPTION:".$description."\r\n"
3012                                ."SUMMARY:".$event_array['title']."\r\n"
3013                                ."LOCATION:".$event_array['location']."\r\n"
3014                                ."END:VEVENT\r\n";
3015                            }
3016                             else
3017                            {
3018                                $tmpattach.=
3019                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
3020                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
3021                                ."DTSTAMP:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3022                                .$organizer
3023                                .$this->mb_wordwrap("UID:".$event_array['uid']."\r\n",74,"\r\n ");
3024
3025                                switch ($metodo) {
3026                                    case 'PUBLISH':
3027                                          $tmpattach.=
3028                                             $this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3029                                                                                        .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3030                                            .$this->mb_wordwrap("DESCRIPTION:".$description."\r\n",74,"\r\n ")
3031                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3032                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ");
3033                                        break;
3034                                    case 'REPLY':
3035                                            $tmpattach.=
3036                                             $this->mb_wordwrap("ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUESTS=0:mailto:".$importAccount['mail']."\r\n",74,"\r\n ")
3037                                            .'DESCRIPTION:\n'."\r\n"
3038                                            .$this->mb_wordwrap("LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n",74,"\r\n ") //Hora no formato UTC
3039                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ")
3040                                            ."SEQUENCE:0\r\n"
3041                                            ."STATUS:CONFIRMED\r\n"
3042                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3043                                            ."TRANSP:OPAQUE\r\n";
3044                                        break;
3045                                    default:
3046                                           $tmpattach.=
3047                                             "DESCRIPTION:".$description."\r\n"
3048                                            ."SUMMARY:".$event_array['title']."\r\n"
3049                                            ."LOCATION:".$event_array['location']."\r\n";
3050                                        break;
3051                                }
3052                                  $tmpattach.= "END:VEVENT\r\n";
3053                            }
3054                           
3055                        }
3056                    $tmpattach.="END:VCALENDAR\r\n\r\n\r\n";   
3057                    return $tmpattach;
3058                }
3059
3060                function mb_wordwrap($str, $width=74, $break="\r\n")
3061                {
3062                    // Return short or empty strings untouched
3063                    if(empty($str) || mb_strlen($str, 'ISSO-8859-1') <= $width)
3064                        return $str;
3065
3066                    $br_width  = mb_strlen($break, 'ISSO-8859-1');
3067                    $str_width = mb_strlen($str, 'ISSO-8859-1');
3068                    $return = '';
3069                    $last_space = false;
3070
3071                    for($i=0, $count=0; $i < $str_width; ++$i, ++$count)
3072                    {
3073                        // If we're at a break
3074                        if (mb_substr($str, $i, $br_width, 'ISSO-8859-1') == $break)
3075                        {
3076                            $count = 0;
3077                            $return .= mb_substr($str, $i, $br_width, 'ISSO-8859-1');
3078                            $i += $br_width - 1;
3079                            continue;
3080                        }
3081
3082                        // Keep a track of the most recent possible break point
3083                        if(mb_substr($str, $i, 1, 'ISSO-8859-1') == " ")
3084                        {
3085                            $last_space = $i;
3086                        }
3087
3088                        // It's time to wrap
3089                        if ($count > $width)
3090                                {
3091                            // There are no spaces to break on!  Going to truncate :(
3092                            if(!$last_space)
3093                                    {
3094                                $return .= $break;
3095                                $count = 0;
3096                            }
3097                            else
3098                            {
3099                                // Work out how far back the last space was
3100                                $drop = $i - $last_space;
3101
3102                                // Cutting zero chars results in an empty string, so don't do that
3103                                if($drop > 0)
3104                                {
3105                                    $return = mb_substr($return, 0, -$drop);
3106                                }
3107
3108                                // Add a break
3109                                $return .= $break;
3110
3111                                // Update pointers
3112                                $i = $last_space + ($br_width - 1);
3113                                $last_space = false;
3114                                $count = 0;
3115                                    }
3116                                }
3117                               
3118                        // Add character from the input string to the output
3119                        $return .= mb_substr($str, $i, 1, 'ISSO-8859-1');
3120                    }
3121                    return $return;
3122                }
3123
3124                function getvCalendarParticipants($pExtParticipants,$pCalId)
3125                                {
3126                    $participants = explode(',', $pExtParticipants);
3127                    $return = '';
3128
3129                    foreach ($participants as $participant)
3130                                      {
3131                        $array = explode('"', $participant);
3132                        $mail = str_replace('<','', str_replace('>','',$array['2']));
3133                        if($mail && $array['1'])
3134                             $return .= 'ATTENDEE;CN='.$array['1'].';RSVP=TRUE:mailto:'.$mail."\r\n";
3135                    }
3136                    $db = $this->getDb();
3137                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3138                    $parts = array();
3139                    while($db->next_record())
3140                        array_push($parts, $db->row());
3141
3142                    $ldap = $this->getLdap();
3143                    foreach ($parts as $part)
3144                    {
3145                        $justthese = array('mail','cn');
3146                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3147                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3148                        $entry = ldap_get_entries($ldap, $search);
3149                        $return .= 'ATTENDEE;CN='.$entry[0]['cn'][0].';RSVP=TRUE:mailto:'.$entry[0]['mail'][0]."\r\n";
3150                                                        }
3151
3152                    return $return;
3153                                                        }
3154                               
3155                function getCalendarParticipantsArray($pCalId)
3156                {
3157                    $db = $this->getDb();
3158                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3159                    $parts = array();
3160                    while($db->next_record())
3161                        array_push($parts, $db->row());
3162
3163                    $ldap = $this->getLdap();
3164                    foreach ($parts as $part)
3165                    {
3166                        $justthese = array('mail','cn');
3167                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3168                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3169                        $entry = ldap_get_entries($ldap, $search);
3170                        $return [$entry[0]['mail'][0]] = array( 'CN'=> $entry[0]['cn'][0],'RSVP'=> 'TRUE' ,'ROLE' => 'REQ-PARTICIPANT');
3171                    }
3172                    return $return;
3173                }
3174
3175                function getvCalendarExternalParticipants($pCalId)
3176                {
3177
3178                    $db = $this->getDb();
3179                    $sql = "SELECT ex_participants FROM phpgw_cal WHERE cal_id = '$pCalId'";
3180                                $db->query($sql);
3181                               
3182                    $parts = array();
3183                    while($db->next_record())
3184                        array_push($parts, $db->row());
3185
3186                                        $participants = explode(',', $parts[0]['ex_participants']);
3187                    $return = '';
3188                                       
3189                                        $participants = unserialize(base64_decode($parts[0]['ex_participants']));
3190
3191                    foreach ($participants as $participant)
3192                    {   
3193                           $part = array();
3194
3195                           if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $participant['mail']))
3196                           {
3197                              $cn = null;
3198                              $mail = null;
3199                              preg_match ("(\"([^\"]*)\")", $participant['mail'], $cn);
3200                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3201
3202                              if($mail[1])
3203                              $part['mail'] =  $mail[1];
3204
3205                              if($cn[1])
3206                                $part['cn'] =  $cn[1];
3207
3208                                                         }
3209                                         else
3210                           if(preg_match("(<[^>]*@[^>]*>)", $participant['mail']))
3211                                                  {
3212                              $mail = null;
3213                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3214                              if($mail[1])
3215                                $part['mail'] =  $mail[1];
3216
3217                                                   }
3218                           else
3219                           if(preg_match("([^ ]*@[^ ]*)", $participant['mail']))
3220                           {
3221                              $mail = null;
3222                              preg_match ('([^ ]*@[^ ]*)', $participant['mail'], $mail);
3223                              if($mail[0])
3224                                $part['mail'] =  $mail[0];
3225
3226                           }
3227
3228                          if(count($part) > 0)
3229                          {
3230                              if($part['cn'])
3231                                                                $return .= 'ATTENDEE;CN='.$part['cn'].';RSVP=TRUE:mailto:'.$part['mail']."\r\n";
3232                              else
3233                                                                $return .= 'ATTENDEE;RSVP=TRUE:mailto:'.$part['mail']."\r\n"; 
3234                             
3235                                      }
3236                                }
3237
3238                    return $return;
3239                        }
3240
3241
3242                function getDb()
3243                {
3244                    include_once('../phpgwapi/inc/class.db.inc.php');
3245                    // Conecta ao banco de dados
3246                    if (is_array($_SESSION['phpgw_info']['expresso']['server']))
3247                        $GLOBALS['phpgw_info']['server'] = $_SESSION['phpgw_info']['expresso']['server'];
3248                    else
3249                        $_SESSION['phpgw_info']['expresso']['server'] = $GLOBALS['phpgw_info']['server'];
3250
3251                    $db = new db();
3252                    $db->Halt_On_Error = 'no';
3253                    $db->connect(
3254                                $_SESSION['phpgw_info']['expresso']['server']['db_name'],
3255                                $_SESSION['phpgw_info']['expresso']['server']['db_host'],
3256                                $_SESSION['phpgw_info']['expresso']['server']['db_port'],
3257                                $_SESSION['phpgw_info']['expresso']['server']['db_user'],
3258                                $_SESSION['phpgw_info']['expresso']['server']['db_pass'],
3259                                $_SESSION['phpgw_info']['expresso']['server']['db_type']
3260                                );
3261                                // Fim Conecta Banco de dados
3262                    return $db;
3263                }
3264
3265                function getLdap()
3266                {
3267                    require_once(dirname(__FILE__).'/../../header.inc.php');
3268                    require_once(dirname(__FILE__).'/../../phpgwapi/inc/class.common.inc.php');
3269   
3270                    $common = new common();
3271                               
3272                    if ( (!empty($GLOBALS['phpgw_info']['server']['ldap_master_host'])) &&
3273                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_dn'])) &&
3274                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_pw'])) )
3275                        {
3276                            $ldap = $common->ldapConnect($GLOBALS['phpgw_info']['server']['ldap_master_host'],
3277                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_dn'],
3278                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_pw']);
3279                        }
3280                        else
3281                        {
3282                            $ldap = $common->ldapConnect();
3283                        }
3284                       
3285                    return $ldap;
3286                }
3287
3288                function getvCalendarOrganizer($pOrganizer)
3289                {
3290
3291                   
3292                       $organizer = array();
3293       
3294                       if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $pOrganizer))
3295                       {
3296                          $cn = null;
3297                          $mail = null;
3298                          preg_match ("(\"([^\"]*)\")", $pOrganizer, $cn);
3299                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3300
3301                          if($mail[1])
3302                          $organizer['mail'] =  $mail[1];
3303
3304                          if($cn[1])
3305                            $organizer['cn'] =  $cn[1];
3306
3307                       }
3308                       else
3309                       if(preg_match("(<[^>]*@[^>]*>)", $pOrganizer))
3310                       {
3311                          $mail = null;
3312                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3313                          if($mail[1])
3314                            $organizer['mail'] =  $mail[1];
3315
3316                       }
3317                       else
3318                       if(preg_match("([^ ]*@[^ ]*)", $pOrganizer))
3319                       {
3320                          $mail = null;
3321                          preg_match ('([^ ]*@[^ ]*)', $pOrganizer, $mail);
3322                          if($mail[0])
3323                            $organizer['mail'] =  $mail[0];
3324
3325                       }
3326                       
3327                       if($organizer['cn']) $return = 'ORGANIZER;CN="'.$organizer['cn'].'":MAILTO:'.$organizer['mail']."\r\n";
3328                       else $return = 'ORGANIZER;MAILTO:'.$organizer['mail']."\r\n";
3329                       
3330                    return $return;
3331                }
3332
3333                /*!
3334                @function send_update
3335                @abstract sends update-messages to certain participants of an event
3336                @syntax send_update($msg_type,$to_notify,$old_event,$new_event=False)
3337                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
3338                @param $to_notify array with numerical user-ids as keys (!) (value is not used)
3339                @param $old_event Event before the change
3340                @param $new_event Event after the change
3341                */
3342                function send_update($msg_type,$to_notify,$old_event,$new_event = False, $user = False)
3343                        {
3344         
3345                        if (!is_array($to_notify)) $to_notify = array();
3346                        $owner = $old_event ? $old_event['owner'] : $new_event['owner'];
3347
3348                        if($owner === -2)
3349                            $to_notify[-2] = 'A';
3350
3351                        $version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
3352                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
3353                 
3354                        /*
3355                         * Caso o evento seja de uma conta compartilha busca obusca o cn e o email da conta
3356                         */
3357                        if($user)
3358                        {
3359                            $ldap = $this->getLdap(); 
3360                            $justthese = array("mail","cn");
3361                            $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3362                            $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3363                            $entry = ldap_get_entries($ldap, $search);
3364                            $sMail = $entry[0]['mail'][0];
3365                            $sCN = $entry[0]['cn'][0];
3366                            $sUN = $user;
3367                        }
3368                        else
3369                        {
3370                            $sMail = $GLOBALS['phpgw_info']['user']['email'];
3371                            $sCN = $GLOBALS['phpgw_info']['user']['fullname'];
3372                            $sUN = $GLOBALS['phpgw_info']['user']['account_id'];
3373                        }
3374                        //------------------------------------------------------------------------------------//
3375                 
3376                    $temp_tz_offset = $this->prefs['common']['tz_offset'];
3377                        $temp_timeformat = $this->prefs['common']['timeformat'];
3378                        $temp_dateformat = $this->prefs['common']['dateformat'];
3379                        $tz_offset = ((60 * 60) * (int)$temp_tz_offset);
3380
3381                        if($old_event != False)
3382                        {
3383                                $t_old_start_time = $this->maketime($old_event['start']);
3384                                if($t_old_start_time < (time() - 86400))
3385                                        return False;
3386                                }
3387
3388                        $temp_user = $GLOBALS['phpgw_info']['user'];
3389                        if (!$user) $user = $this->owner;
3390                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
3391                        $this->prefs = $GLOBALS['phpgw_info']['user']['preferences'];
3392
3393                        $event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
3394                        if($old_event != False)
3395                        {
3396                                $old_starttime = $t_old_start_time - $GLOBALS['phpgw']->datetime->tz_offset;
3397                        }
3398                        $starttime = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
3399                        $endtime   = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
3400
3401                        switch($msg_type)
3402                        {
3403                                case MSG_DELETED:
3404                                        $action = lang('Canceled');
3405                                        $msg = 'Canceled';
3406                                        $msgtype = '"calendar";';
3407                                        $method = 'cancel';
3408                                        $typesend = 1;
3409                                        break;
3410                                case MSG_MODIFIED:
3411                                        $action = lang('Modified');
3412                                        $msg = 'Modified';
3413                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3414                                        $method = 'request';
3415                                        $typesend = 2;
3416                                        break;
3417                                case MSG_ADDED:
3418                                        $action = lang('Added');
3419                                        $msg = 'Added';
3420                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3421                                        $method = 'request';
3422                                        $typesend = 3;
3423                                        break;
3424                                case MSG_REJECTED:
3425                                        $action = lang('Rejected');
3426                                        $msg = 'Response';
3427                                        $msgtype = '"calendar";';
3428                                        $method = 'reply';
3429                                        $typesend = 4;
3430                                        break;
3431                                case MSG_TENTATIVE:
3432                                        $action = lang('Tentative');
3433                                        $msg = 'Response';
3434                                        $msgtype = '"calendar";';
3435                                        $method = 'reply';
3436                                        $typesend = 5;
3437                                        break;
3438                                case MSG_ACCEPTED:
3439                                        $action = lang('Accepted');
3440                                        $msg = 'Response';
3441                                        $msgtype = '"calendar";';
3442                                        $method = 'reply';
3443                                        $typesend = 6;
3444                                        break;
3445                                case MSG_ALARM:
3446                                        $action = lang('Alarm');
3447                                        $msg = 'Alarm';
3448                                        $msgtype = '"calendar";';
3449                                        $method = 'publish';    // duno if thats right
3450                                        $typesend = 7;
3451                                        break;
3452                                default:
3453                                        $method = 'publish';
3454                                        $typesend = 8;
3455                        }
3456                        $notify_msg = $this->prefs['calendar']['notify'.$msg];
3457                        if (empty($notify_msg))
3458                                $notify_msg = $this->prefs['calendar']['notifyAdded'];  // use a default
3459                       
3460                        $details = array(                       // event-details for the notify-msg
3461                                'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
3462                                'action'      => $action,
3463                        );
3464                        $event_arr = $this->event2array($event);
3465                        foreach($event_arr as $key => $val)
3466                        {
3467                                $details[$key] = $val['data'];
3468                        }
3469                       
3470                        $details['participants'] = implode("\n",$details['participants']);
3471
3472                        $details['link'] = $GLOBALS['phpgw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uicalendar.view&cal_id='.$event['id'];
3473                        // if url is only a path, try guessing the rest ;-)
3474                        if ($GLOBALS['phpgw_info']['server']['webserver_url'][0] == '/')
3475                        {
3476                                $details['link'] = ($GLOBALS['phpgw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
3477                                        ($GLOBALS['phpgw_info']['server']['hostname'] ? $GLOBALS['phpgw_info']['server']['hostname'] : 'localhost').
3478                                        $details['link'];
3479                        }
3480                       
3481                        //Seta o email usando phpmailer
3482                        define('PHPGW_INCLUDE_ROOT','../');     
3483                        define('PHPGW_API_INC','../phpgwapi/inc');     
3484                        include_once(PHPGW_API_INC.'/class.phpmailer.inc.php');
3485                        $mail = new PHPMailer();
3486                        $mail->IsSMTP();
3487                        $boemailadmin = CreateObject('emailadmin.bo');
3488                        $emailadmin_profile = $boemailadmin->getProfileList();
3489                        $emailadmin = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
3490               
3491                        $mail->Host = $emailadmin['smtpServer'];
3492                        $mail->Port = $emailadmin['smtpPort'];
3493                        $mail->From = $sMail;
3494                        $mail->FromName = $sCN;
3495                        $mail->IsHTML(true);
3496                        //Inicializa vari?vel de retorno.
3497                        $returncode=true;               
3498                        // Aqui e enviado o email
3499                        foreach($to_notify as $userid => $statusid)
3500                        {
3501                                $mail->ClearAttachments();
3502                               
3503                                $userid = (int)$userid;
3504
3505                                if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g' || ($sUN == $userid &&  $msg_type != MSG_ALARM))
3506                                    continue;   // dont notify rejected participants or to == send
3507                               
3508                                if($userid != $sUN  ||  $msg_type == MSG_ALARM)
3509                                {
3510                                        print_debug('Msg Type',$msg_type);
3511                                       
3512                                        print_debug('UserID',$userid);
3513
3514                                        $preferences = CreateObject('phpgwapi.preferences',$userid);
3515                                        $part_prefs = $preferences->read_repository();
3516
3517                                        if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event))
3518                                        {
3519                                                continue;
3520                                        }
3521                                        $GLOBALS['phpgw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
3522                                        $details['to-fullname'] = $GLOBALS['phpgw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
3523
3524                                        $to = $preferences->email_address($userid);
3525                                       
3526                                       
3527                                        if( $userid === -2 )
3528                                        {
3529                                                $to = htmlspecialchars_decode( $event['organizer'] );
3530                                        }
3531                                       
3532                                        if (empty($to) || $to[0] == '@' || $to[0] == '$')       // we have no valid email-address
3533                                        {
3534                                                //echo "<p>bocalendar::send_update: Empty email adress for user '".$details['to-fullname']."' ==> ignored !!!</p>\n";
3535                                                continue;
3536                                        }
3537                                        print_debug('Email being sent to',$to);
3538
3539                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
3540                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
3541                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
3542
3543                                        $GLOBALS['phpgw']->datetime->tz_offset = ((60 * 60) * (int)$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']);
3544
3545                                        if($old_starttime)
3546                                        {
3547                                                $details['olddate'] = $GLOBALS['phpgw']->common->show_date($old_starttime);
3548                                        }
3549                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3550                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3551                                       
3552                                       
3553                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3554                                       
3555                                        switch($part_prefs['calendar']['update_format'])
3556                                        {
3557                                                case  'extended':
3558                                                        //$body .= "\n\n".lang('Event Details follow').":\n";
3559                                                        $body = '';
3560                                                        $body .= "<br>".lang('Event Details follow')." :: ";
3561                                                        foreach($event_arr as $key => $val)
3562                                                        {
3563                                                                // titulo
3564                                                                if($key =='title')
3565                                                                {
3566                                                                        $var1 = $val['field'];
3567                                                                        $vardata1 = $details[$key];
3568                                                                }
3569                                                                //descricao
3570                                                                if($key =='description')
3571                                                                {
3572                                                                        $var2 = $val['field'];
3573                                                                        $vardata2 = $details[$key];
3574                                                                }
3575                                                                //dt inicio
3576                                                                if($key =='startdate')
3577                                                                {
3578                                                                        switch(trim($part_prefs['common']['dateformat']))
3579                                                                        {
3580                                                                               
3581                                                                                case ($part_prefs['common']['dateformat'] === "m/d/Y" || $part_prefs['common']['dateformat'] === "m-d-Y" || $part_prefs['common']['dateformat'] === "m.d.Y"):
3582                                                                                        $var3 = $val['field'];
3583                                                                                        $vardata3 = $details[$key];
3584                                                                                        $newmounth3 = substr($vardata3,0,2);
3585                                                                                        $newday3 = substr($vardata3,3,2);
3586                                                                                        $newyear3 = substr($vardata3,6,4);
3587                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3588                                                                                        break;
3589                                                                                       
3590                                                                                case    ($part_prefs['common']['dateformat'] === "Y/d/m" || $part_prefs['common']['dateformat'] === "Y-d-m" || $part_prefs['common']['dateformat'] === "Y.d.m"):
3591
3592                                                                                        $var3 = $val['field'];
3593                                                                                        $vardata3 = $details[$key];
3594                                                                                        $newyear3 = substr($vardata3,0,4);
3595                                                                                        $newday3 = substr($vardata3,5,2);
3596                                                                                        $newmounth3 = substr($vardata3,8,2);
3597                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3598                                                                                        break;
3599
3600                                                                                case ($part_prefs['common']['dateformat'] === "Y/m/d" || $part_prefs['common']['dateformat'] === "Y-m-d" || $part_prefs['common']['dateformat'] === "Y.m.d"):
3601
3602                                                                                        $var3 = $val['field'];
3603                                                                                        $vardata3 = $details[$key];
3604                                                                                        $newyear3 = substr($vardata3,0,4);
3605                                                                                        $newmounth3 = substr($vardata3,5,2);
3606                                                                                        $newday3 = substr($vardata3,8,2);
3607                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3608                                                                                        break;
3609
3610                                                                                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"):
3611                                                                               
3612                                                                                        $var3 = $val['field'];
3613                                                                                        $vardata3 = $details[$key];
3614                                                                                        $newday3 = substr($vardata3,0,2);
3615                                                                                        $newmounth3 = substr($vardata3,3,2);
3616                                                                                        $newyear3 = substr($vardata3,6,4);
3617                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3618                                                                                        break;
3619                                                                       
3620                                                                        }
3621                                                                       
3622                                                                }
3623                                                                //dt final
3624                                                                if($key =='enddate')
3625                                                                {
3626                                                                        $var4 = $val['field'];
3627                                                                        $vardata4 = $details[$key];
3628                                                                }
3629                                                                //localizacao
3630                                                                if($key =='location')
3631                                                                {
3632                                                                        $var8 = $val['field'];
3633                                                                        $vardata8 = $details[$key];
3634                                                                }
3635                                                                //participantes
3636                                                                if($key =='participants')
3637                                                                {
3638                                                                        $var5 = $val['field'];
3639                                                                        foreach($val['data'] as $NewKey => $NewVal)
3640                                                                        {
3641                                                                                //Research inside of ldap ( Pesquisa dentro do ldap )
3642                                                                                $newvalue = $this->so->search_uidNumber($to);
3643                                                                                foreach($newvalue as $tmp)
3644                                                                                {
3645                                                                                        $tmpmail = $tmp['mail'][0];
3646                                                                                        $tmpuid = $tmp['uidnumber'][0];
3647                                                                                        if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
3648                                                                                        {
3649                                                                                                        if($typesend == 3)
3650                                                                                                        {
3651
3652                                                                                                                $lang1 = lang("To See Commitment");
3653                                                                                                                $varbuttom = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id={$event['id']}&date=$newall3' method='POST'>
3654                                                                                                                                                                  <input type='submit' value='$lang1'>
3655                                                                                                                                                                   </form>";
3656                                                                                                                $lang2 = lang("To accept");
3657                                                                                                                $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\")'>";
3658                                                                                                               
3659                                                                                                                $lang6 = lang("Tentative");
3660                                                                                                                $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\")'>";
3661                                                                                                               
3662
3663                                                                                                                $lang3 = lang("To reject");
3664                                                                                                                $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\")'>";
3665                                                                                                               
3666                                                                                                                $lang4 = lang("Alarm");
3667                                                                                                                $varbuttom3 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uialarm.manager method='POST'>
3668                                                                                                                                                                  <input type='submit' value='$lang4'>
3669                                                                                                                                                                  <input type='hidden' name='cal_id' value=$event[id]>
3670                                                                                                                                                                   </form>";
3671                                                                                                                                                                   
3672                                                                                                                $lang5 = lang("Suggest new hour");
3673                                                                                                                $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'>
3674                                                                                                                                                                  <input type='submit' value='$lang5'>
3675                                                                                                                                                                   </form>";
3676                                                                                                        }
3677                                                                                                        else
3678                                                                                                        {
3679                                                                                                                        $varbuttom  = "";
3680                                                                                                                        $varbuttom1 = "";
3681                                                                                                                        $varbuttom2 = "";
3682                                                                                                                        $varbuttom3 = "";
3683                                                                                                                        $varbuttom4 = "";
3684                                                                                                                        $varbuttom5 = "";
3685                                                                                                        }
3686                                                                                        }
3687                                                                                        // It only mounts variavel with the name of the participants of the list ( Monta a variavel somente com o nome dos participantes da lista)
3688                                                                                        if($typesend == 3)
3689                                                                                        {
3690                                                                                                list($tmpvardata5,$tmp2vardata5) = explode("(",$NewVal);
3691                                                                                                $vardata5 = $tmpvardata5."<br>";
3692                                                                                        }
3693                                                                                        else
3694                                                                                        {
3695                                                                                                $vardata5 = $NewVal."<br>";
3696                                                                                        }
3697                                                                               
3698                                                                                }
3699                                                                                $vardata6 .= $vardata5;
3700                                                                                unset($vardata5);
3701                                                                        }
3702                                                                }               
3703                                                        }
3704                                                        //To mount the message as text/html (Para montar a mensagem como text/html - /phpgwapi/inc/class.send.inc.php )
3705                                                        $content_type = "text/html";
3706                                                        //It mounts the body of the message (Monta o corpo da mensagem)
3707                                                       
3708                                                        // A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
3709                                                        if(!PHPGW_APP_TPL)
3710                                                         define ("PHPGW_APP_TPL",PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3711                                                       
3712                                                                $body = CreateObject('phpgwapi.Template',PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3713                                                        $body->set_file(Array('calendar' => 'body_email.tpl'));
3714                                                        $body->set_block('calendar','list');
3715                                                        $var = Array(
3716                                                                'script'                        => $script,
3717                                                                'subject'                       => $body1,
3718                                                                'var1'                          => $var1,
3719                                                                'vardata1'                      => $vardata1,
3720                                                                'var2'                          => $var2,
3721                                                                'vardata2'                      => $vardata2,
3722                                                                'var3'                          => $var3,
3723                                                                'vardata3'                      => $vardata3,
3724                                                                'var4'                          => $var4,
3725                                                                'vardata4'                      => $vardata4,
3726                                                                'var5'                          => $var5,
3727                                                                'vardata6'                      => $vardata6,
3728                                                                'var8'                          => $var8,
3729                                                                'vardata8'                      => $vardata8,
3730                                                                'varbuttom'                     => $varbuttom,
3731                                                                'varbuttom1'            => $varbuttom1,
3732                                                                'varbuttom2'            => $varbuttom2,
3733                                                                'varbuttom3'            => $varbuttom3,
3734                                                                'varbuttom4'            => $varbuttom4,
3735                                                                'varbuttom5'            => $varbuttom5
3736                                                        );
3737                                                        $body->set_var($var);
3738                                                        $tmpbody = $body->fp('out','list');
3739                                                                                                               
3740                                                        break;
3741
3742                                                case 'ical':
3743                                                        $content_type = "calendar; method=$method; name=calendar.ics";
3744/*                                                      if ($body != '')
3745                                                        {
3746                                                                $boundary = '----Message-Boundary';
3747                                                                $body .= "\n\n\n$boundary\nContent-type: text/$content_type\n".
3748                                                                        "Content-Disposition: inline\nContent-transfer-encoding: 7BIT\n\n";
3749                                                                $content_type = '';
3750                                                        }
3751*/
3752                                                        $body = ExecMethod('calendar.boicalendar.export',array(
3753                                                                'l_event_id'  => $event['id'],
3754                                                                'method'      => $method,
3755                                                                'chunk_split' => False
3756                                                        ));
3757                                                        break;
3758                                        }
3759                                       
3760                                        $mail->AddAddress($to);
3761                                        $mail->Body = $tmpbody;     
3762                                        $mail->From = $sMail;
3763                                        $mail->FromName = $sCN;
3764                                        $mail->Sender = $mail->From;
3765                                        $mail->SenderName = $mail->FromName;
3766                                        $mail->Subject = $subject;
3767                                        unset($vardata5);
3768                                        unset($vardata6);
3769                                       
3770                                        // Envia aviso ao participante.
3771                                        if(!$mail->Send()) {                           
3772                                                $returncode = false;
3773                                                $errorInfo['participants'] = $mail->ErrorInfo;
3774                        }
3775
3776                                        $mail->ClearAddresses();   
3777
3778                                }
3779                            }
3780
3781                        if(!is_object($this->ex_participants))
3782                        {
3783                            include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
3784                            $objexP = new exParticipants();
3785                            $objexP->setParticipantsBySerializable($this->ex_participants);
3786                                }
3787                                else
3788                            $objexP = $this->ex_participants;
3789
3790                       
3791                        if($msg_type === MSG_ADDED && count($this->extAdded) > 0)
3792                               $extMails = $this->extAdded; 
3793                        else if($msg_type === MSG_DELETED && count($this->extDeleted) > 0)
3794                                $extMails = $this->extDeleted; 
3795                        else
3796                            $extMails = array_diff($objexP->getParticipantsMailsArray(), $this->alreadyExtNotifieds);
3797                               
3798                        if(count($extMails) > 0){
3799                                $mail->ClearAllRecipients();
3800                             
3801                                $to = array();
3802                                if(!$subject) {
3803                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3804                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3805                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3806                                }
3807                               
3808                                foreach($extMails as $index => $ex_participant){
3809                                        $ex_participant = trim($ex_participant);
3810                                        $ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
3811                                                if($ex_participant)
3812                                                        $to[] = $ex_participant;
3813                                }               
3814                               
3815                                foreach($to as $i => $to_array)
3816                                        $mail->AddAddress($to_array);
3817                               
3818                                $_body = explode("<hr size='1' width='100%'>",$tmpbody);
3819                                $tmpbody = $_body[0] ? $_body[0] : $subject ;
3820                                $tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($objexP->getParticipantsMailsString());
3821                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[description]."<br>";
3822                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
3823                                $tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
3824                                .lang("This message was sent by server. You must send a message to sender to confirm this event")."<br>"
3825                                .lang("This is an external event. Even if it added to your expresso its can be changed any time at all")."</font><br>";
3826                               
3827                                if ($GLOBALS['bocalendar']->so->cal->event[start][month] > 10)
3828                                        $event_month=$GLOBALS['bocalendar']->so->cal->event[start][month];
3829                                else
3830                                        $event_month="0".$GLOBALS['bocalendar']->so->cal->event[start][month];
3831                                //attach extern vcalendar/icalendar (ics)                       
3832                                // define('context','$GLOBALS.bocalendar.so.cal.event');
3833                               
3834                                $evt = $GLOBALS['bocalendar']->so->cal->event;
3835                                                                 
3836                                /*
3837                                 * Cria Arqvuio ICS
3838                                 */
3839                                require_once dirname(__FILE__).'/../../services/class.servicelocator.php';
3840                                $icalService = ServiceLocator::getService('ical');
3841
3842                                if($msg_type == MSG_DELETED)
3843                                {
3844                                        $icalService->createICal(strtoupper($method));
3845                                        $icalService->addEvent(
3846                                            $old_event['start']['year'].'-'.$old_event['start']['month'].'-'.$old_event['start']['mday'].' '.$old_event['start']['hour'].':'.$old_event['start']['min'].':00',
3847                                            $old_event['end']['year'].'-'.$old_event['end']['month'].'-'.$old_event['end']['mday'].' '.$old_event['end']['hour'].':'.$old_event['end']['min'].':00',
3848                                            array($sMail => array('CN'=> $sCN)),
3849                                            $old_event['title'],
3850                                            $old_event['description'],
3851                                            $old_event['location'],
3852                                            false,
3853                                            false,
3854                                            false,
3855                                            $old_event['uid']
3856                                            );
3857                                }
3858                                else
3859                                {
3860                                        $attendee = array();
3861                                        foreach($to as $value)
3862                                            $attendee[$value] = array('RSVP' => 'TRUE','ROLE' => 'REQ-PARTICIPANT');
3863
3864                                        $attendee =  array_merge($attendee,$this->getCalendarParticipantsArray($evt['id']));
3865                                        $icalService->createICal(strtoupper($method));
3866                                        $icalService->addEvent(
3867                                            $evt['start']['year'].'-'.$evt['start']['month'].'-'.$evt['start']['mday'].' '.$evt['start']['hour'].':'.$evt['start']['min'].':00',
3868                                            $evt['end']['year'].'-'.$evt['end']['month'].'-'.$evt['end']['mday'].' '.$evt['end']['hour'].':'.$evt['end']['min'].':00',
3869                                            array($sMail => array('CN'=> $sCN)),
3870                                            $evt['title'],
3871                                            $evt['description'],
3872                                            $evt['location'],
3873                                            $attendee,
3874                                            false,
3875                                            false,
3876                                            $evt['uid']
3877                                            );
3878
3879                                }
3880
3881
3882                                $tmpattach = $icalService->getICal();
3883                                //-------------------------------------------------//
3884                               
3885                                if($tmpattach){                                 
3886                                        $tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
3887                                        srand((double)microtime()*1000000);
3888                                        $random_number = rand(100000000,999999999);
3889                                        $newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
3890                                        $filename = $tempdir . $newfilename;
3891                                        $attach_fd = fopen($filename,"w+");
3892                                        fwrite($attach_fd,$tmpattach);
3893                                        $mail->AddAttachment($filename, "extern.ics", "base64", "text/plain"); // "application/octet-stream"
3894                                        fclose($attach_fd);
3895                                }
3896                                $mail->From = $sMail;
3897                                $mail->FromName = $sCN;
3898                                $mail->Sender = $mail->From;
3899                                $mail->SenderName = $mail->FromName;
3900                                $mail->Subject = lang("External event from Expresso");
3901                                $mail->Body = $tmpbody;
3902                                                                                                                                               
3903                                if(!$mail->Send())
3904                                {
3905                                        $returncode=false;
3906                                        $errorInfo['ex_participants'] = $mail->ErrorInfo;
3907                                }
3908                                else
3909                                {
3910                                        $returncode=true;
3911                                }
3912                        }
3913
3914
3915                        if((is_int($this->user) && $this->user != $temp_user['account_id']) ||
3916                                (is_string($this->user) && $this->user != $temp_user['account_lid']))
3917                        {
3918                                $GLOBALS['phpgw_info']['user'] = $temp_user;
3919                        }       
3920
3921                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $temp_tz_offset;
3922                        $GLBOALS['phpgw']->datetime->tz_offset = ((60 * 60) * $temp_tz_offset);
3923                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $temp_timeformat;
3924                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
3925                       
3926                        // Notifica por email o criador do compromisso, com as poss?veis falhas.                                               
3927                        if($errorInfo) {
3928                                $tmpbody = "<font color='red'>".lang("The following commitment had problems for DELIVERING the NOTIFICATION messages.").".</font><br>";
3929                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
3930                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";                         
3931                                $tmpbody.= "<br><u>".lang("Failed to delivery")."</u><br>";
3932                                $failed = false;                               
3933                                if(strstr($errorInfo['participants'],"recipients_failed")){
3934                                        $failed = explode("recipients_failed",$errorInfo['participants']);
3935                                        $tmpbody.= lang("to").": ".$failed[1];
3936                                }
3937                                if(strstr($errorInfo['ex_participants'],"recipients_failed")){
3938                                        $failed = explode("recipients_failed",$errorInfo['ex_participants']);
3939                                        $tmpbody.= lang("to").": ".$failed[1];
3940                                }                       
3941                                if(!$failed) {
3942                                        $tmpbody.= lang("Description").":<br>";
3943                                        $tmpbody.= $errorInfo['participants'];
3944                                        $tmpbody.= "<br>".$errorInfo['ex_participants'];
3945                                }
3946                                $tmpbody.= "<br>".lang("Subject").": ".$subject;
3947                                // Reinicializa o objeto, devido ao erro anterior na entrega.
3948                               
3949                                $mail = new PHPMailer();
3950                                $mail->IsSMTP();
3951                                $mail->Host = $emailadmin['smtpServer'];
3952                                $mail->Port = $emailadmin['smtpPort'];
3953                                $mail->From = $sMail;
3954                                $mail->FromName = $sCN;
3955                                $mail->Sender = $mail->From;
3956                                $mail->SenderName = $mail->FromName;
3957                                $mail->IsHTML(True);
3958                                $mail->Subject = lang("calendar event")." - ".lang("email notification");                                                       
3959                                $mail->Body = $tmpbody;                                 
3960                                $mail->AddAddress($sMail);
3961                                if(!$mail->Send())                     
3962                                        $returncode = false;
3963                                else
3964                                        $returncode =  true;
3965                        }
3966                        return $returncode;
3967                }
3968               
3969               
3970               
3971                /**
3972                 * @license http://www.gnu.org/copyleft/gpl.html GPL
3973                 * @author Prognus Software Livre (http://www.prognus.com.br)
3974                 */
3975                function send_suggestion_external_owner($cal_id, $uid, $to, $time_suggest, $array_data_inicio, $array_data_final, $title, $description, $location, $ex_participants,$user = false)
3976                {
3977
3978                    if($cal_id)
3979                        $event =  $this->so->read_entry($cal_id);
3980                    else
3981                    {
3982                        $event = $this->restore_from_appsession();
3983                        $this->so->add_entry( $event , false);
3984                    }
3985                   
3986                    $this->so->cal->set_status($event['id'],$user,2);
3987
3988
3989                    if($user && $user != $GLOBALS['phpgw_info']['user']['account_id'])
3990                    {
3991                        $ldap = $this->getLdap();
3992                        $justthese = array("mail","cn");
3993                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3994                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3995                        $entry = ldap_get_entries($ldap, $search);
3996                        $ownerMail = $entry[0]['mail'][0];
3997                        $ownerCN = $entry[0]['cn'][0];
3998                     }
3999                     else
4000                     {
4001                        $ownerMail = $GLOBALS['phpgw_info']['user']['email'];
4002                        $ownerCN = $GLOBALS['phpgw_info']['user']['fullname'];
4003                     }
4004                     
4005                    require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
4006                    $icalService = ServiceLocator::getService('ical');
4007                    $dia_inicio = $array_data_inicio[0];
4008                    $mes_inicio = $array_data_inicio[1];
4009                    $ano_inicio = $array_data_inicio[2];
4010                    $hora_inicio = $time_suggest['hora_inicio'];
4011                    $minuto_inicio = $time_suggest['minuto_inicio'];
4012                    $dia_final = $array_data_final[0];
4013                    $mes_final = $array_data_final[1];
4014                    $ano_final = $array_data_final[2];
4015                    $hora_final = $time_suggest['hora_final'];
4016                    $minuto_final = $time_suggest['minuto_final'];
4017
4018                    $dtStart = $array_data_inicio[2] . '/' .
4019                               $array_data_inicio[1] . '/' .
4020                               $array_data_inicio[0] . ' ' .
4021                               $time_suggest['hora_inicio'] . ':' .
4022                               $time_suggest['minuto_inicio'] . ':00';
4023
4024                    $dtEnd = $array_data_final[2] . '/' .
4025                             $array_data_final[1] . '/' .
4026                             $array_data_final[0] . ' ' .
4027                             $time_suggest['hora_final'] . ':' .
4028                             $time_suggest['minuto_final'] . ':00';
4029
4030                    $icalService->createICal('REPLY');
4031
4032                    $other = array( 'X-MICROSOFT-CDO-IMPORTANCE' => '1',
4033                                    'X-EXPRESSO-SUGGESTION-HOUR' => '1',
4034                                    'CLASS' => 'PUBLIC',
4035                                    'PRIORITY' => '5',
4036                                    'SEQIENCE' => '0',
4037                                    'TRANSP' => 'OPAQUE');
4038
4039                    /* Corpo do email */
4040                    $tmpbody2 = lang("The sender suggested a new hours for the appointment");
4041                    $tmpbody2.= " <br /> <b>" . lang("Title") . ":</b> $title";
4042                    $tmpbody2.= " <br /> <b>" . lang("Details") . ":</b> <br /> <br /> <b>" . lang("Start") . "  </b>" . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4043                    $tmpbody2.= " <br /> <b>" . lang("End") . " </b>" . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "<br><br><br><br>";
4044                    $tmpbody = lang("The sender suggested a new hours for the appointment");
4045                    $tmpbody.= " \r\n " . lang("Title") . ": $title";
4046                    $tmpbody.= " \r\n " . lang("Suggestion") . ": \r\n \r\n " . lang("Start") . "  " . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4047                    $tmpbody.= " \r\n " . lang("End") . " " . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "";
4048
4049                    $icalService->addEvent($dtStart,
4050                            $dtEnd,
4051                            $to,
4052                            $title,
4053                            utf8_encode($tmpbody),
4054                            $location,
4055                            array($ownerMail => array('CN' => $ownerCN, 'PARTSTAT' => 'TENTATIVE')),
4056                            $other,
4057                            false,
4058                            $uid
4059                    );
4060                   
4061                    $tmpattach =  $icalService->getICal();                   
4062                   
4063                    $mailService = ServiceLocator::getService('mail');
4064                    $mailService->addStringAttachment($tmpattach, 'suggestion.ics', 'application/ics');
4065                    $mailService->addStringAttachment($tmpattach, 'vcalendar.ics', 'text/calendar; charset=utf-8; method=REPLY;', '7bit', 'inline');
4066                    $mailService->sendMail($to, $ownerMail, $title, $tmpbody2);
4067                     
4068                    return $event['id'];                   
4069                }               
4070               
4071                function send_alarm($alarm)
4072                {
4073                        //echo "<p>bocalendar::send_alarm("; print_r($alarm); echo ")</p>\n";
4074                       
4075                        $GLOBALS['phpgw_info']['user']['account_id'] = $this->owner = $alarm['owner'];
4076
4077                        if (!$alarm['enabled'] || !$alarm['owner'] || !$alarm['cal_id'] || !($event = $this->so->read_entry($alarm['cal_id'])))
4078                        {
4079                                return False;   // event not found
4080                        }
4081                        if ($alarm['all'])
4082                        {
4083                                $to_notify = $event['participants'];
4084                        }
4085                        elseif ($this->check_perms(PHPGW_ACL_READ,$event))      // checks agains $this->owner set to $alarm[owner]
4086                        {
4087                                $to_notify[$alarm['owner']] = 'A';
4088                        }
4089                        else
4090                        {
4091                                return False;   // no rights
4092                        }
4093                        return $this->send_update(MSG_ALARM,$to_notify,$event,False,$alarm['owner']);
4094                }
4095
4096                function get_alarms($event_id)
4097                {
4098                        return $this->so->get_alarm($event_id);
4099                }
4100
4101                function alarm_today($event,$today,$starttime)
4102                {
4103                        $found = False;
4104                        @reset($event['alarm']);
4105                        $starttime_hi = $GLOBALS['phpgw']->common->show_date($starttime,'Hi');
4106                        $t_appt['month'] =$GLOBALS['phpgw']->common->show_date($today,'m');
4107                        $t_appt['mday'] = $GLOBALS['phpgw']->common->show_date($today,'d');
4108                        $t_appt['year'] = $GLOBALS['phpgw']->common->show_date($today,'Y');
4109                        $t_appt['hour'] = $GLOBALS['phpgw']->common->show_date($starttime,'H');
4110                        $t_appt['min']  = $GLOBALS['phpgw']->common->show_date($starttime,'i');
4111                        $t_appt['sec']  = 0;
4112                        $t_time = $this->maketime($t_appt) - $GLOBALS['phpgw']->datetime->tz_offset;
4113                        $y_time = $t_time - 86400;
4114                        $tt_time = $t_time + 86399;
4115                        print_debug('T_TIME',$t_time.' : '.$GLOBALS['phpgw']->common->show_date($t_time));
4116                        print_debug('Y_TIME',$y_time.' : '.$GLOBALS['phpgw']->common->show_date($y_time));
4117                        print_debug('TT_TIME',$tt_time.' : '.$GLOBALS['phpgw']->common->show_date($tt_time));
4118                        while(list($key,$alarm) = each($event['alarm']))
4119                        {
4120                                if($alarm['enabled'])
4121                                {
4122                                        print_debug('TIME',$alarm['time'].' : '.$GLOBALS['phpgw']->common->show_date($alarm['time']).' ('.$event['id'].')');
4123                                        if($event['recur_type'] != MCAL_RECUR_NONE)   /* Recurring Event */
4124                                        {
4125                                                print_debug('Recurring Event');
4126                                                if($alarm['time'] > $y_time && $GLOBALS['phpgw']->common->show_date($alarm['time'],'Hi') < $starttime_hi && $alarm['time'] < $t_time)
4127                                                {
4128                                                        $found = True;
4129                                                }
4130                                        }
4131                                        elseif($alarm['time'] > $y_time && $alarm['time'] < $t_time)
4132                                        {
4133                                                $found = True;
4134                                        }
4135                                }
4136                        }
4137                        print_debug('Found',$found);
4138                        return $found;
4139                }
4140
4141                function prepare_recipients(&$new_event,$old_event,$userSend)
4142                {
4143                        //Verifica se ouve alguem deletado
4144                        foreach($old_event['participants'] as $key => $value)
4145                           if(!array_key_exists($key, $new_event['participants']))
4146                                {
4147                               $this->deleted[$key] = $value;
4148                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4149                                }
4150                        //Verifica se ouve alguem adicionado
4151                        foreach($new_event['participants'] as $key => $value)
4152                           if(!array_key_exists($key, $old_event['participants']))
4153                                {
4154                               $this->added[$key] = $value;
4155                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4156                        }
4157                       
4158                        //Verifica se ouve alguem modificado
4159                        foreach($new_event['participants'] as $key => $value)
4160                        {
4161                            if(array_key_exists($key, $old_event['participants']))                       
4162                                {
4163                                if($old_event['participants'][$key] != $value)
4164                                {
4165                                    $this->modified[$key] = $value; 
4166                                    $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4167                                }
4168                                }
4169                        }
4170                         //Verificando alterações em usuarios externos
4171                         include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
4172                         $extOld = new exParticipants();
4173                         $extNew = new exParticipants();
4174                         
4175                         $extOld->setParticipantsBySerializable($old_event['ex_participants']);
4176                         $extNew->setParticipantsBySerializable($new_event['ex_participants']);
4177                       
4178                         $oldArray = $extOld->getParticipantsMailsArray();
4179                         $newArray = $extNew->getParticipantsMailsArray();
4180                         
4181                        //Verifica se ouve alguem deletado
4182                        $this->extDeleted = array_diff($oldArray, $newArray);
4183                       
4184                        //Verifica se ouve alguem adicionado
4185                        $this->extAdded = array_diff($newArray, $oldArray);
4186                       
4187                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extDeleted);
4188                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extAdded);
4189                        //---------------------------------------------------------------------------------//
4190                       
4191                        if(count($this->added) > 0 || count($this->extAdded))
4192                                $this->send_update(MSG_ADDED,$this->added,'',$new_event,$userSend);
4193                       
4194                        if(count($this->modified) > 0)
4195                                $this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event,$userSend);
4196                       
4197                        if(count($this->deleted) > 0 || count($this->extDeleted))
4198                                $this->send_update(MSG_DELETED,$this->deleted,$old_event,false,$userSend);
4199                                               
4200                }
4201
4202                function remove_doubles_in_cache($firstday,$lastday)
4203                {
4204                        $already_moved = Array();
4205                        for($v=$firstday;$v<=$lastday;++$v)
4206                        {
4207                                if (!$this->cached_events[$v])
4208                                {
4209                                        continue;
4210                                }
4211                                $cached = $this->cached_events[$v];
4212                                $this->cached_events[$v] = array();
4213                                while (list($g,$event) = each($cached))
4214                                {
4215                                        $end = date('Ymd',$this->maketime($event['end']));
4216                                        print_debug('EVENT',_debug_array($event,False));
4217                                        print_debug('start',$start);
4218                                        print_debug('v',$v);
4219
4220                                        if (!isset($already_moved[$event['id']]) || $event['recur_type'] && $v > $end)
4221                                        {
4222                                                $this->cached_events[$v][] = $event;
4223                                                $already_moved[$event['id']] = 1;
4224                                                print_debug('Event moved');
4225                                        }
4226                                }
4227                        }
4228                }
4229
4230                function get_dirty_entries($lastmod=-1)
4231                {
4232                        $events = false;
4233                        $event_ids = $this->so->cal->list_dirty_events($lastmod);
4234                        if(is_array($event_ids))
4235                        {
4236                                foreach($event_ids as $key => $id)
4237                                {
4238                                        $events[$id] = $this->so->cal->fetch_event($id);
4239                                }
4240                        }
4241                        unset($event_ids);
4242
4243                        $rep_event_ids = $this->so->cal->list_dirty_events($lastmod,$true);
4244                        if(is_array($rep_event_ids))
4245                        {
4246                                foreach($rep_event_ids as $key => $id)
4247                                {
4248                                        $events[$id] = $this->so->cal->fetch_event($id);
4249                                }
4250                        }
4251                        unset($rep_event_ids);
4252
4253                        return $events;
4254                }
4255
4256                function _debug_array($data)
4257                {
4258                        echo '<br>UI:';
4259                        _debug_array($data);
4260                }
4261
4262                /*!
4263                @function rejected_no_show
4264                @abstract checks if event is rejected from user and he's not the owner and dont want rejected
4265                @param $event to check
4266                @returns True if event should not be shown
4267                */
4268                function rejected_no_show($event)
4269                {
4270                        $ret = !$this->prefs['calendar']['show_rejected'] &&
4271                                $event['owner'] != $this->owner &&
4272                                $event['participants'][$this->owner] == 'R';
4273                        //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";
4274                        return $ret;
4275                }
4276
4277                /* This is called only by list_cals().  It was moved here to remove fatal error in php5 beta4 */
4278                function list_cals_add($id,&$users,&$groups)
4279                {
4280                        $name = $GLOBALS['phpgw']->common->grab_owner_name($id);
4281                        if (($type = $GLOBALS['phpgw']->accounts->get_type($id)) == 'g')
4282                        {
4283                                $arr = &$groups;
4284                        }
4285                        else
4286                        {
4287                                $arr = &$users;
4288                        }
4289                        $arr[$name] = Array(
4290                                'grantor' => $id,
4291                                'value'   => ($type == 'g' ? 'g_' : '') . $id,
4292                                'name'    => $name
4293                        );
4294                }
4295
4296                /*!
4297                @function list_cals
4298                @abstract generate list of user- / group-calendars for the selectbox in the header
4299                @returns alphabeticaly sorted array with groups first and then users
4300                */
4301                function list_cals()
4302                {
4303                        $users = $groups = array();
4304                        foreach($this->grants as $id => $rights)
4305                        {
4306                                $this->list_cals_add($id,$users,$groups);
4307                        }
4308                       
4309                        //by JakJr, melhora de performance na abertura da agenda
4310                        /*if ($memberships = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']))
4311                        {
4312                                foreach($memberships as $group_info)
4313                                {
4314                                        $this->list_cals_add($group_info['account_id'],$users,$groups);
4315
4316                                        if ($account_perms = $GLOBALS['phpgw']->acl->get_ids_for_location($group_info['account_id'],PHPGW_ACL_READ,'calendar'))
4317                                        {
4318                                                foreach($account_perms as $id)
4319                                                {
4320                                                        $this->list_cals_add($id,$users,$groups);
4321                                                }
4322                                        }
4323                                }
4324                        }*/
4325                        uksort($users,'strnatcasecmp');
4326                        uksort($groups,'strnatcasecmp');
4327
4328                        return $users + $groups;        // users first and then groups, both alphabeticaly
4329                }
4330
4331          function translate($key,$vars=false, $not_found='*' )
4332          {
4333            if ($this->async)
4334              return $GLOBALS['phpgw']->translation->translate_async($key, $vars);
4335            return lang($key, $vars);
4336          }
4337
4338                /*!
4339                @function event2array
4340                @abstract create array with name, translated name and readable content of each attributes of an event
4341                @syntax event2array($event,$sep='<br>')
4342                @param $event event to use
4343                @returns array of attributes with fieldname as key and array with the 'field'=translated name \
4344                        'data' = readable content (for participants this is an array !)
4345                */
4346                function event2array($event)
4347                {
4348                       
4349                       
4350                  $var['title'] = Array(
4351                                'field'         => $this->translate('Title'),
4352                                'data'          => $event['title']
4353                        );
4354
4355                        // Some browser add a \n when its entered in the database. Not a big deal
4356                        // this will be printed even though its not needed.
4357                        $var['description'] = Array(
4358                                'field' => $this->translate('Description'),
4359                                'data'  => $event['description']
4360                        );
4361
4362                        $var['ex_participants'] = Array(
4363                                'field' => $this->translate('External Participants'),
4364                                'data'  => $event['ex_participants']
4365                        );
4366                       
4367                        $cats = Array();
4368                        $this->cat->categories($this->bo->owner,'calendar');
4369                        if(strpos($event['category'],','))
4370                        {
4371                                $cats = explode(',',$event['category']);
4372                        }
4373                        else
4374                        {
4375                                $cats[] = $event['category'];
4376                        }
4377                        foreach($cats as $cat_id)
4378                        {
4379                                list($cat) = $this->cat->return_single($cat_id);
4380                                $cat_string[] = $cat['name'];
4381                        }
4382                        $var['category'] = Array(
4383                                'field' => $this->translate('Category'),
4384                                'data'  => implode(', ',$cat_string)
4385                        );
4386
4387                        $var['location'] = Array(
4388                                'field' => $this->translate('Location'),
4389                                'data'  => $event['location']
4390                        );
4391
4392                        $var['startdate'] = Array(
4393                                'field' => $this->translate('Start Date/Time'),
4394                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset),
4395                        );
4396
4397                        $var['enddate'] = Array(
4398                                'field' => $this->translate('End Date/Time'),
4399                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset)
4400                        );
4401
4402                        $pri = Array(
4403                                1       => lang('Low'),
4404                                2       => lang('Normal'),
4405                                3       => lang('High')
4406                        );
4407                        $var['priority'] = Array(
4408                                'field' => lang('Priority'),
4409                                'data'  => $pri[$event['priority']]
4410                        );
4411
4412                        $owner = $event['owner'];
4413
4414                        $owner_name = ( $owner === -2 )? $event['organizer'] : $GLOBALS['phpgw']->common->grab_owner_name( $owner );
4415
4416                        $var['owner'] = Array(
4417                                'field' => lang('Created By'),
4418                                'data'  => $owner_name
4419                        );
4420
4421                        $var['updated'] = Array(
4422                                'field' => lang('Updated'),
4423                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['modtime']) - $GLOBALS['phpgw']->datetime->tz_offset)
4424                        );
4425
4426                        if($event['public']){
4427                                $type = lang('Public');
4428                        }else if (!$event['public'] && $event['type'] == 'E'){
4429                                $type = lang('Restrict');
4430                        }else{
4431                                $type = lang('Private');
4432                        }
4433
4434                        $var['access'] = Array(
4435                                'field' => lang('Access'),
4436                                'data'  => $type
4437                        );
4438
4439                        if(@isset($event['groups'][0]))
4440                        {
4441                                $cal_grps = '';
4442                $event_groups_count = count($event['groups']);
4443                                for($i=0;$i<$event_groups_count;++$i)
4444                                {
4445                                        if($GLOBALS['phpgw']->accounts->exists($event['groups'][$i]))
4446                                        {
4447                                                $cal_grps .= ($i>0?'<br>':'').$GLOBALS['phpgw']->accounts->id2name($event['groups'][$i]);
4448                                        }
4449                                }
4450
4451                                $var['groups'] = Array(
4452                                        'field' => lang('Groups'),
4453                                        'data'  => $cal_grps
4454                                );
4455                        }
4456
4457                        $participants = array();
4458                        foreach($event['participants'] as $user => $short_status)
4459                        {
4460                                if($GLOBALS['phpgw']->accounts->exists($user))
4461                                {
4462                                        $participants[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user).' ('.$this->get_long_status($short_status).')';
4463                                }
4464                        }
4465                        $var['participants'] = Array(
4466                                'field' => $this->translate('Participants'),
4467                                'data'  => $participants
4468                        );
4469
4470                        // Repeated Events
4471                        if($event['recur_type'] != MCAL_RECUR_NONE)
4472                        {
4473                                $str = lang($this->rpt_type[$event['recur_type']]);
4474
4475                                $str_extra = array();
4476                                if ($event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['year'] != 0)
4477                                {
4478                                        $recur_end = $this->maketime($event['recur_enddate']);
4479                                        if($recur_end != 0)
4480                                        {
4481                                                $recur_end -= $GLOBALS['phpgw']->datetime->tz_offset;
4482                                                $str_extra[] = lang('ends').': '.lang($GLOBALS['phpgw']->common->show_date($recur_end,'l')).', '.$this->long_date($recur_end).' ';
4483                                        }
4484                                }
4485                                // only weekly uses the recur-data (days) !!!
4486                                if($event['recur_type'] == MCAL_RECUR_WEEKLY)
4487                                {
4488                                        $repeat_days = array();
4489                                        foreach ($this->rpt_day as $mcal_mask => $dayname)
4490                                        {
4491                                                if ($event['recur_data'] & $mcal_mask)
4492                                                {
4493                                                        $repeat_days[] = lang($dayname);
4494                                                }
4495                                        }
4496                                        if(count($repeat_days))
4497                                        {
4498                                                $str_extra[] = lang('days repeated').': '.implode(', ',$repeat_days);
4499                                        }
4500                                }
4501                                if($event['recur_interval'] != 0)
4502                                {
4503                                        $str_extra[] = lang('Interval').': '.$event['recur_interval'];
4504                                }
4505
4506                                if(count($str_extra))
4507                                {
4508                                        $str .= ' ('.implode(', ',$str_extra).')';
4509                                }
4510
4511                                $var['recure_type'] = Array(
4512                                        'field' => lang('Repetition'),
4513                                        'data'  => $str,
4514                                );
4515                        }
4516
4517                        if (!isset($this->fields))
4518                        {
4519                                $this->custom_fields = CreateObject('calendar.bocustom_fields');
4520                                $this->fields = &$this->custom_fields->fields;
4521                                $this->stock_fields = &$this->custom_fields->stock_fields;
4522                        }
4523                        foreach($this->fields as $field => $data)
4524                        {
4525                                if (!$data['disabled'])
4526                                {
4527                                        if (isset($var[$field]))
4528                                        {
4529                                                $sorted[$field] = $var[$field];
4530                                        }
4531                                        elseif (!isset($this->stock_fields[$field]) && strlen($event[$field]))  // Custom field
4532                                        {
4533                                                $lang = lang($name = substr($field,1));
4534                                                $sorted[$field] = array(
4535                                                        'field' => $lang == $name.'*' ? $name : $lang,
4536                                                        'data'  => $event[$field]
4537                                                );
4538                                        }
4539                                }
4540                                unset($var[$field]);
4541                        }
4542                        foreach($var as $name => $v)
4543                        {
4544                                $sorted[$name] = $v;
4545
4546                        }
4547                        return $sorted;
4548                }
4549
4550                /*!
4551                @function check_set_default_prefs
4552                @abstract sets the default prefs, if they are not already set (on a per pref. basis)
4553                @note It sets a flag in the app-session-data to be called only once per session
4554                */
4555                function check_set_default_prefs()
4556                {
4557                        if (($set = $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar')))
4558                        {
4559                                return;
4560                        }
4561                        $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar','set');
4562
4563                        $default_prefs = $GLOBALS['phpgw']->preferences->default['calendar'];
4564
4565                        $subject = $this->translate('Calendar Event') . ' - $$action$$: $$startdate$$ $$title$$'."\n";
4566                        $defaults = array(
4567                                'defaultcalendar' => 'week',
4568                                'mainscreen_showevents' => '0',
4569                                'summary'         => 'no',
4570                                'receive_updates' => 'no',
4571                                'update_format'   => 'extended',        // leave it to extended for now, as iCal kills the message-body
4572                                'notifyAdded'     => $subject . $this->translate ('You have a meeting scheduled for %1',array('$$startdate$$')),
4573                                'notifyCanceled'  => $subject . $this->translate ('Your meeting scheduled for %1 has been canceled',array('$$startdate$$')),
4574                                'notifyModified'  => $subject . $this->translate ('Your meeting that had been scheduled for %1 has been rescheduled to %2',array('$$olddate$$','$$startdate$$')),
4575                                'notifyResponse'  => $subject . $this->translate ('On %1 %2 %3 your meeting request for %4', array('$$date$$','$$fullname$$','$$action$$','$$startdate$$')),
4576                                'notifyAlarm'     => $this->translate('Alarm for %1 at %2 in %3',array('$$title$$','$$startdate$$','$$location$$')) . "\n" . $this->translate('Here is your requested alarm.'),
4577                                'show_rejected'   => '0',
4578                                'hide_event_conflict'   => '0',
4579                                'display_status'  => '1',
4580                                'weekdaystarts'   => 'Monday',
4581                                'workdaystarts'   => '9',
4582                                'workdayends'     => '17',
4583                                'interval'        => '30',
4584                                'defaultlength'   => '60',
4585                                'planner_start_with_group' => $GLOBALS['phpgw']->accounts->name2id('Default'),
4586                                'planner_intervals_per_day'=> '4',
4587                                'defaultfilter'   => 'all',
4588                                'default_private' => '0',
4589                                'display_minicals'=> '1',
4590                                'print_black_white'=>'0'
4591                        );
4592                        foreach($defaults as $var => $default)
4593                        {
4594                                if (!isset($default_prefs[$var]) || $default_prefs[$var] == '')
4595                                {
4596                                        $GLOBALS['phpgw']->preferences->add('calendar',$var,$default,'default');
4597                                        $need_save = True;
4598                                }
4599                        }
4600                        if ($need_save)
4601                        {
4602                                $prefs = $GLOBALS['phpgw']->preferences->save_repository(False,'default');
4603                                $this->prefs['calendar'] = $prefs['calendar'];
4604                        }
4605                        if ($this->prefs['calendar']['send_updates'] && !isset($this->prefs['calendar']['receive_updates']))
4606                        {
4607                                $this->prefs['calendar']['receive_updates'] = $this->prefs['calendar']['send_updates'];
4608                                $GLOBALS['phpgw']->preferences->add('calendar','receive_updates',$this->prefs['calendar']['send_updates']);
4609                                $GLOBALS['phpgw']->preferences->delete('calendar','send_updates');
4610                                $prefs = $GLOBALS['phpgw']->preferences->save_repository();
4611                        }
4612                }
4613
4614                // return array with all infolog categories (for xmlrpc)
4615                function categories($complete = False)
4616                {
4617                        return $GLOBALS['server']->categories($complete);
4618                }
4619        }
4620?>
Note: See TracBrowser for help on using the repository browser.