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

Revision 5845, 163.1 KB checked in by acoutinho, 12 years ago (diff)

Ticket #2434 - Erro ao importar um novo evento agenda antiga

  • 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                                        for($i=0;$i<count($parts);$i++)
1255                                        {
1256                                                if (($accept_type = substr($parts[$i],-1,1)) == '0' || (int)$accept_type > 0)
1257                                                {
1258                                                        $accept_type = 'U';
1259                                                }
1260                                                $acct_type = $GLOBALS['phpgw']->accounts->get_type((int)$parts[$i]);
1261                                                if($acct_type == 'u' || $acct_type == 's')
1262                                                {
1263                                                        $part[(int)$parts[$i]] = $accept_type;
1264                                                }
1265                                                elseif($acct_type == 'g')
1266                                                {
1267                                                        $part[(int)$parts[$i]] = $accept_type;
1268                                                        $groups[] = $parts[$i];
1269                                                        /* This pulls ALL users of a group and makes them as participants to the event */
1270                                                        /* I would like to turn this back into a group thing. */
1271                                                        $acct = CreateObject('phpgwapi.accounts',(int)$parts[$i]);
1272                                                        $members = $acct->member((int)$parts[$i]);
1273                                                        unset($acct);
1274                                                        if($members == False)
1275                                                        {
1276                                                                continue;
1277                                                        }
1278                                                        while($member = each($members))
1279                                                        {
1280                                                                $part[$member[1]['account_id']] = $accept_type;
1281                                                        }
1282                                                }
1283                                        }
1284                                }
1285                                else
1286                                {
1287                                        $part = False;
1288                                }
1289
1290                                if($part)
1291                                {
1292                                        @reset($part);
1293                                        while(list($key,$accept_type) = each($part))
1294                                        {
1295                                                $this->so->add_attribute('participants',$accept_type,(int)$key);
1296                                        }
1297                                }
1298
1299                                if($groups)
1300                                {
1301                                        @reset($groups);
1302                                        $this->so->add_attribute('groups',(int)$group_id);
1303                                }
1304
1305                                $event = $this->get_cached_event();
1306                                if(!is_int($minparts))
1307                                {
1308                                        $minparts = $this->owner;
1309                                }
1310                                if(!@isset($event['participants'][$l_cal['owner']]))
1311                                {
1312                                        $this->so->add_attribute('owner',$minparts);
1313                                }
1314                                else
1315                                {
1316                                        $this->so->add_attribute('owner',$l_cal['owner']);
1317                                }
1318                                $this->so->add_attribute('priority',$l_cal['priority']);
1319
1320                                foreach($l_cal as $name => $value)
1321                                {
1322                                        if ($name[0] == '#')    // Custom field
1323                                        {
1324                                                $this->so->add_attribute($name,stripslashes($value));
1325                                        }
1326                                }
1327                                if (isset($_POST['preserved']) && is_array($preserved = unserialize(stripslashes($_POST['preserved']))))
1328                                {
1329                                        foreach($preserved as $name => $value)
1330                                        {
1331                                                switch($name)
1332                                                {
1333                                                        case 'owner':
1334                                                                $this->so->add_attribute('participants',$value,$l_cal['owner']);
1335                                                                break;
1336                                                        default:
1337                                                                $this->so->add_attribute($name,str_replace(array('&amp;','&quot;','&lt;','&gt;'),array('&','"','<','>'),$value));
1338                                                }
1339                                        }
1340                                }
1341                                $event = $this->get_cached_event();
1342
1343                                if ($l_cal['alarmdays'] > 0 || $l_cal['alarmhours'] > 0 ||$l_cal['alarmminutes'] > 0)
1344                                {
1345                                        $offset = ($l_cal['alarmdays'] * 24 * 3600) +
1346                                                ($l_cal['alarmhours'] * 3600) + ($l_cal['alarmminutes'] * 60);
1347
1348                                        $time = $this->maketime($event['start']) - $offset;
1349
1350                                        $event['alarm'][] = Array(
1351                                                'time'    => $time,
1352                                                'offset'  => $offset,
1353                                                'owner'   => $this->owner,
1354                                                'enabled' => 1,
1355                                                'repeat'  => $this->repetido, // para repetir alarme;
1356                                                'init_rept' => $init_rept, // inicio repeticao;
1357                                                'end_rept' => $end_rept, // fim repeticao;
1358                                                'rpt_wdays' => $rpt_wdays // dias repeticao da semana;
1359                                        );
1360                                }
1361
1362                                $this->store_to_appsession($event);
1363                                $datetime_check = $this->validate_update($event);
1364                                print_debug('bo->validated_update() returnval',$datetime_check);
1365                                if($datetime_check)
1366                                {
1367                                        if (!$send_to_ui)
1368                                        {
1369                                                return array($datetime_check => 'invalid input data');
1370                                        }
1371                                        ExecMethod($ui_return,
1372                                                Array(
1373                                                        'cd'            => $datetime_check,
1374                                                        'readsess'      => 1
1375                                                )
1376                                        );
1377                                        if(!$params['from_mobile'])
1378                                                $GLOBALS['phpgw']->common->phpgw_exit(True);
1379                                        else
1380                                                return;
1381                                }
1382
1383                            $overlapping_events = $this->event_overlap( $event, $send_to_ui, $prefix );
1384
1385                            if( $overlapping_events )
1386                                return( $overlapping_events );
1387                        }
1388
1389                                $event['ex_participants'] = $this->ex_participants->getParticipantsSerializable();
1390                       
1391                        if($event['owner'] != $GLOBALS['phpgw_info']['user']['account_id']) $userSend = $event['owner'];
1392                        else $userSend = false;
1393       
1394                        if(!$event['id'])
1395                        {
1396                                /** Whenever a recurrent event is edit in a way that a new 
1397                                 * exception is created, an exception must be added to
1398                                 * the old event. This is necessary to keep consistency
1399                                 * with synchornization solutions in accordancy to
1400                                 * the iCalendar RFC.
1401                                 */
1402                                $old_event = $this->so->read_entry($_POST['cal']['reference']);
1403
1404                                $date = $_POST['cal']['date'];
1405                                $year  = substr($date,0,4);
1406                                $month = substr($date,4,2);
1407                                $day   = substr($date,6,2);
1408
1409                                $exception_time = mktime($old_event['start']['hour'],$old_event['start']['min'],0,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
1410                                $old_event['recur_exception'][] = (int)$exception_time;
1411                                $this->so->add_entry($old_event,false);
1412                           
1413                           
1414                                $this->so->add_entry($event,false);
1415                                print_debug('New Event ID',$event['id']);
1416                                $send_type = MSG_ADDED;
1417                        }
1418                        else
1419                        {
1420                                print_debug('Updating Event ID',$event['id']);
1421                                $new_event = $event;
1422                                $old_event = $this->read_entry($event['id']);
1423                                // if old event has alarm and the start-time changed => update them
1424                                //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";
1425                                if ($old_event['alarm'] &&
1426                                        $this->maketime($old_event['start']) != $this->maketime($event['start']))
1427                                {
1428                                        $this->so->delete_alarms($old_event['id']);
1429                                        foreach($old_event['alarm'] as $id => $alarm)
1430                                        {
1431                                                $alarm['time'] = $this->maketime($event['start']) - $alarm['offset'];
1432                                                $event['alarm'][] = $alarm;
1433                                        }
1434                                        //echo "updated alarms<pre>".print_r($event['alarm'],True)."</pre>\n";
1435                                }
1436                                $this->so->cal->event = $event;
1437                                $this->so->add_entry($event,false);
1438                                $this->prepare_recipients($new_event,$old_event,$userSend);
1439                                $send_type = MSG_MODIFIED;
1440                        }
1441                     
1442                        //Retira da lista usuarios ja notificados
1443                        $to_notify = $event['participants'];
1444                        foreach ($this->alreadyNotifieds as $key => $value)
1445                            if(array_key_exists($value,$to_notify))
1446                                unset ($to_notify[$value]);
1447                        //------------------------------------------------//
1448                           
1449                        if(count($to_notify) > 0 && $userSend !== -2)   
1450                            $this->send_update( $send_type,$to_notify,'',$this->get_cached_event(),$userSend);
1451
1452                        $date = sprintf("%04d%02d%02d",$event['start']['year'],$event['start']['month'],$event['start']['mday']);
1453                        if($send_to_ui)
1454                        {
1455                                $this->read_sessiondata();
1456                                if ($this->return_to)
1457                                {
1458                                        $GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.$this->return_to);
1459                                        $GLOBALS['phpgw']->common->phpgw_exit();
1460                                }
1461                                Execmethod($ui_index);
1462                        }
1463                        else
1464                        {
1465                                return (int)$event['id'];
1466                        }
1467
1468                        return True;
1469                }
1470
1471                function event_overlap( $event, $send_to_ui = false, $prefix = "calendar.uicalendar" ,$user = false)
1472                {
1473                    $event_ids = array();
1474
1475                                if($event['id'])
1476                                {
1477                                        $event_ids[] = $event['id'];
1478                                }
1479                                if($event['reference'])
1480                                {
1481                                        $event_ids[] = $event['reference'];
1482                                }
1483
1484                    if (isset($this->repetido) and $this->repetido > 0)
1485                    {
1486                                    $events = $this->expand_repetition($event);
1487                                    $overlapping_events = False;
1488                                    foreach($events as $evt){
1489                                        $overlap = $this->overlap(
1490                                            $evt['start'],
1491                                            $evt['end'],
1492                                            $evt['participants'],
1493                                            $evt['owner'],
1494                                            $event_ids);
1495                                        if ($overlap)
1496                                        {
1497                                            if (!$overlapping_events)
1498                                            {
1499                                                $overlapping_events = Array();
1500                                            }
1501                                            array_push($overlapping_events, $overlap);
1502                                        }
1503                                    }
1504                                }
1505                    else
1506                    {
1507                                    $overlapping_events = $this->overlap(
1508                                        $this->maketime($event['start']),
1509                                        $this->maketime($event['end']),
1510                                        $event['participants'],
1511                                        $event['owner'],
1512                                        $event_ids
1513                                    );
1514                                }
1515                                     
1516                        if($overlapping_events)
1517                        {
1518                            $this->store_to_appsession( $event );
1519                                if($send_to_ui)
1520                                {
1521                                        unset($GLOBALS['phpgw_info']['flags']['noheader']);
1522                                        unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
1523                                    ExecMethod("$prefix.overlap",
1524                                                Array(
1525                                                        'o_events'      => $overlapping_events,
1526                                                    'this_event'        => $event,
1527                                                    'this_account' => $user
1528                                                )
1529                                        );
1530
1531                                    if( $prefix === "calendar.uicalendar" )
1532                                                $GLOBALS['phpgw']->common->phpgw_exit(True);
1533                                }
1534
1535                            return( $overlapping_events );
1536                        }
1537
1538                    return( false );
1539                }
1540
1541                /* Private functions */
1542                function read_holidays($year=0)
1543                {
1544                        if(!$year)
1545                        {
1546                                $year = $this->year;
1547                        }
1548                        $holiday = CreateObject('calendar.boholiday');
1549                        $holiday->prepare_read_holidays($year,$this->owner);
1550                        $this->cached_holidays = $holiday->read_holiday();
1551                        unset($holiday);
1552                }
1553
1554                function user_is_a_member($event,$user)
1555                {
1556                        @reset($event['participants']);
1557                        $uim = False;
1558                        $security_equals = $GLOBALS['phpgw']->accounts->membership($user);
1559                        while(!$uim && $event['participants'] && $security_equals && list($participant,$status) = each($event['participants']))
1560                        {
1561                                if($GLOBALS['phpgw']->accounts->get_type($participant) == 'g')
1562                                {
1563                                        @reset($security_equals);
1564                                        while(list($key,$group_info) = each($security_equals))
1565                                        {
1566                                                if($group_info['account_id'] == $participant)
1567                                                {
1568                                                        return True;
1569                                                        $uim = True;
1570                                                }
1571                                        }
1572                                }
1573                        }
1574                        return $uim;
1575                }
1576
1577                function maketime($time)
1578                {
1579                        return mktime(intval($time['hour']),intval($time['min']),intval($time['sec']),intval($time['month']),intval($time['mday']),intval($time['year']));
1580                }
1581
1582                /*!
1583                @function time2array
1584                @abstract returns a date-array suitable for the start- or endtime of an event from a timestamp
1585                @syntax time2array($time,$alarm=0)
1586                @param $time the timestamp for the values of the array
1587                @param $alarm (optional) alarm field of the array, defaults to 0
1588                @author ralfbecker
1589                */
1590                function time2array($time,$alarm = 0)
1591                {
1592                        return array(
1593                                'year'  => (int)(date('Y',$time)),
1594                                'month' => (int)(date('m',$time)),
1595                                'mday'  => (int)(date('d',$time)),
1596                                'hour'  => (int)(date('H',$time)),
1597                                'min'   => (int)(date('i',$time)),
1598                                'sec'   => (int)(date('s',$time)),
1599                                'alarm' => (int)($alarm)
1600                        );
1601                }
1602
1603                /*!
1604                @function set_recur_date
1605                @abstract set the start- and enddates of a recuring event for a recur-date
1606                @syntax set_recur_date(&$event,$date)
1607                @param $event the event which fields to set (has to be the original event for start-/end-times)
1608                @param $date  the recuring date in form 'Ymd', eg. 20030226
1609                @author ralfbecker
1610                */
1611                function set_recur_date(&$event,$date)
1612                {
1613                        $org_start = $this->maketime($event['start']);
1614                        $org_end   = $this->maketime($event['end']);
1615                        $start = mktime($event['start']['hour'],$event['start']['min'],0,substr($date,4,2),substr($date,6,2),substr($date,0,4));
1616                        $end   = $org_end + $start - $org_start;
1617                        $event['start'] = $this->time2array($start);
1618                        $event['end']   = $this->time2array($end);
1619                }
1620
1621                function fix_update_time(&$time_param)
1622                {
1623                        if (isset($time_param['str']))
1624                        {
1625                                if (!is_object($this->jscal))
1626                                {
1627                                        $this->jscal = CreateObject('phpgwapi.jscalendar');
1628                                }
1629                                $time_param += $this->jscal->input2date($time_param['str'],False,'mday');
1630                                unset($time_param['str']);
1631                        }
1632                        if ($this->prefs['common']['timeformat'] == '12')
1633                        {
1634                                if ($time_param['ampm'] == 'pm')
1635                                {
1636                                        if ($time_param['hour'] <> 12)
1637                                        {
1638                                                $time_param['hour'] += 12;
1639                                        }
1640                                }
1641                                elseif ($time_param['ampm'] == 'am')
1642                                {
1643                                        if ($time_param['hour'] == 12)
1644                                        {
1645                                                $time_param['hour'] -= 12;
1646                                        }
1647                                }
1648
1649                                if($time_param['hour'] > 24)
1650                                {
1651                                        $time_param['hour'] -= 12;
1652                                }
1653                        }
1654                }
1655
1656                function validate_update($event)
1657                {
1658                        $error = 0;
1659                        // do a little form verifying
1660                        if (!count($event['participants']))
1661                        {
1662                                $error = 43;
1663                        }
1664                        elseif ($event['title'] == '')
1665                        {
1666                                $error = 40;
1667                        }
1668                        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))
1669                        {
1670                                $error = 41;
1671                        }
1672                        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))
1673                        {
1674                                $error = 42;
1675                        }
1676                        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)
1677                        {
1678                                if ($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 1)
1679                                {
1680                                        $error = 42;
1681                                }
1682                        }
1683                       
1684                        return $error;
1685                }
1686
1687                /*!
1688                @function participants_not_rejected($participants,$event)
1689                @abstract checks if any of the $particpants participates in $event and has not rejected it
1690                */
1691                function participants_not_rejected($participants,$event)
1692                {
1693                        //echo "participants_not_rejected()<br>participants =<pre>"; print_r($participants); echo "</pre><br>event[participants]=<pre>"; print_r($event['participants']); echo "</pre>\n";
1694                        foreach($participants as $uid => $status)
1695                        {
1696                                //echo "testing event[participants][uid=$uid] = '".$event['participants'][$uid]."'<br>\n";
1697                                if (isset($event['participants'][$uid]) && $event['participants'][$uid] != 'R' &&
1698                                        $status != 'R')
1699                                {
1700                                        return True;    // found not rejected participant in event
1701                                }
1702                        }
1703                        return False;
1704                }
1705               
1706                function overlap($starttime,$endtime,$participants,$owner=0,$id=0,$restore_cache=False)
1707                {
1708//                      $retval = Array();
1709//                      $ok = False;
1710
1711/* This needs some attention.. by commenting this chunk of code it will fix bug #444265 */
1712
1713                        if($restore_cache)
1714                        {
1715                                $temp_cache_events = $this->cached_events;
1716                        }
1717
1718//                      $temp_start = (int)$GLOBALS['phpgw']->common->show_date($starttime,'Ymd');
1719//                      $temp_start_time = (int)($GLOBALS['phpgw']->common->show_date($starttime,'Hi');
1720//                      $temp_end = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Ymd');
1721//                      $temp_end_time = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Hi');
1722                        $temp_start = (int)(date('Ymd',$starttime));
1723                        $temp_start_time = (int)(date('Hi',$starttime));
1724                        $temp_end = (int)(date('Ymd',$endtime));
1725                        $temp_end_time = (int)(date('Hi',$endtime));
1726                        if($this->debug)
1727                        {
1728                                echo '<!-- Temp_Start: '.$temp_start.' -->'."\n";
1729                                echo '<!-- Temp_End: '.$temp_end.' -->'."\n";
1730                        }
1731
1732                        $users = Array();
1733                        if(count($participants))
1734                        {
1735                                while(list($user,$status) = each($participants))
1736                                {
1737                                        $users[] = $user;
1738                                }
1739                        }
1740                        else
1741                        {
1742                                $users[] = $this->owner;
1743                        }
1744
1745                        $possible_conflicts = $this->store_to_cache(
1746                                Array(
1747                                        'smonth'        => substr(strval($temp_start),4,2),
1748                                        'sday'  => substr(strval($temp_start),6,2),
1749                                        'syear' => substr(strval($temp_start),0,4),
1750                                        'emonth'        => substr(strval($temp_end),4,2),
1751                                        'eday'  => substr(strval($temp_end),6,2),
1752                                        'eyear' => substr(strval($temp_end),0,4),
1753                                        'owner' => $users
1754                                )
1755                        );
1756
1757                        if($this->debug)
1758                        {
1759                                echo '<!-- Possible Conflicts ('.($temp_start - 1).'): '.count($possible_conflicts[$temp_start - 1]).' -->'."\n";
1760                                echo '<!-- Possible Conflicts ('.$temp_start.'): '.count($possible_conflicts[$temp_start]).' '.count($id).' -->'."\n";
1761                        }
1762
1763                        if($possible_conflicts[$temp_start] || $possible_conflicts[$temp_end])
1764                        {
1765                                if($temp_start == $temp_end)
1766                                {
1767                                        if($this->debug)
1768                                        {
1769                                                echo '<!-- Temp_Start == Temp_End -->'."\n";
1770                                        }
1771                                        @reset($possible_conflicts[$temp_start]);
1772                                        while(list($key,$event) = each($possible_conflicts[$temp_start]))
1773                                        {
1774                                                $found = False;
1775                                                if($id)
1776                                                {
1777                                                        @reset($id);
1778                                                        while(list($key,$event_id) = each($id))
1779                                                        {
1780                                                                if($this->debug)
1781                                                                {
1782                                                                        echo '<!-- $id['.$key.'] = '.$id[$key].' = '.$event_id.' -->'."\n";
1783                                                                        echo '<!-- '.$event['id'].' == '.$event_id.' -->'."\n";
1784                                                                }
1785                                                                if($event['id'] == $event_id)
1786                                                                {
1787                                                                        $found = True;
1788                                                                }
1789                                                        }
1790                                                }
1791                                                if($this->debug)
1792                                                {
1793                                                        echo '<!-- Item found: '.$found.' -->'."<br>\n";
1794                                                }
1795                                                if(!$found)
1796                                                {
1797                                                        if($this->debug)
1798                                                        {
1799                                                                echo '<!-- Checking event id #'.$event['id'];
1800                                                        }
1801                                                        $temp_event_start = sprintf("%d%02d",$event['start']['hour'],$event['start']['min']);
1802                                                        $temp_event_end = sprintf("%d%02d",$event['end']['hour'],$event['end']['min']);
1803//                                                      if((($temp_start_time <= $temp_event_start) && ($temp_end_time >= $temp_event_start) && ($temp_end_time <= $temp_event_end)) ||
1804                                                        if(($temp_start_time <= $temp_event_start &&
1805                                                                $temp_end_time > $temp_event_start &&
1806                                                                $temp_end_time <= $temp_event_end ||
1807                                                                $temp_start_time >= $temp_event_start &&
1808                                                                $temp_start_time < $temp_event_end &&
1809                                                                $temp_end_time >= $temp_event_end ||
1810                                                                $temp_start_time <= $temp_event_start &&
1811                                                                $temp_end_time >= $temp_event_end ||
1812                                                                $temp_start_time >= $temp_event_start &&
1813                                                                $temp_end_time <= $temp_event_end) &&
1814                                                                $this->participants_not_rejected($participants,$event))
1815                                                        {
1816                                                                if($this->debug)
1817                                                                {
1818                                                                        echo ' Conflicts';
1819                                                                }
1820                                                                $retval[] = $event['id'];
1821                                                        }
1822                                                        if($this->debug)
1823                                                        {
1824                                                                echo ' -->'."\n";
1825                                                        }
1826                                                }
1827                                        }
1828                                }
1829                        }
1830                        else
1831                        {
1832                                $retval = False;
1833                        }
1834
1835                        if($restore_cache)
1836                        {
1837                                $this->cached_events = $temp_cache_events;
1838                        }
1839
1840                        return $retval;
1841                }
1842
1843                /*!
1844                @function check_perms( )
1845                @syntax check_perms($needed,$event=0,$other=0)
1846                @abstract Checks if the current user has the necessary ACL rights
1847                @author ralfbecker
1848                @discussion The check is performed on an event or general on the cal of an other user
1849                @param $needed necessary ACL right: PHPGW_ACL_{READ|EDIT|DELETE}
1850                @param $event event as array or the event-id or 0 for general check
1851                @param $other uid to check (if event==0) or 0 to check against $this->owner
1852                @note Participating in an event is considered as haveing read-access on that event, \
1853                        even if you have no general read-grant from that user.
1854                */
1855                function check_perms($needed,$event=0,$other=0)
1856                {
1857                        $event_in = $event;
1858                       
1859                        if (is_int($event) && $event == 0)
1860                        {
1861                                $owner = $other > 0 ? $other : $this->owner;
1862                        }
1863                        else
1864                        {
1865                                if (!is_array($event))
1866                                {
1867                                        $event = $this->so->read_entry((int) $event);
1868                                }
1869                                if (!is_array($event))
1870                                {
1871                                        if ($this->xmlrpc)
1872                                        {
1873                                                $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
1874                                        }
1875                                        return False;
1876                                }
1877                                $owner = $event['owner'];
1878                                $private = $event['public'] == False || $event['public'] == 0;
1879                        }
1880                        $user = $GLOBALS['phpgw_info']['user']['account_id'];
1881                        $grants = $this->grants[$owner];
1882
1883                        if (is_array($event) && $needed == PHPGW_ACL_READ)
1884                        {
1885                                // Check if the $user is one of the participants or has a read-grant from one of them
1886                                //
1887                                foreach($event['participants'] as $uid => $accept)
1888                                {
1889                                        if ($this->grants[$uid] & PHPGW_ACL_READ || $uid == $user)
1890                                        {
1891                                                $grants |= PHPGW_ACL_READ;
1892                                                // if the $user is one of the participants read-grant private (restricted) too.
1893                                                if($uid == $user || ($this->grants[$uid] & PHPGW_ACL_PRIVATE)) {
1894                                                        $grants |= PHPGW_ACL_PRIVATE;
1895                                                }
1896                                                //break;
1897                                        }
1898                                }
1899                        }
1900
1901                        if ($GLOBALS['phpgw']->accounts->get_type($owner) == 'g' && $needed == PHPGW_ACL_ADD)
1902                        {
1903                                $access = False;        // a group can't be the owner of an event
1904                        }
1905                        else
1906                        {
1907                                $access = $user == $owner || $grants & $needed && (!$private || $grants & PHPGW_ACL_PRIVATE);
1908                        }
1909                        //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";
1910
1911                        return $access;
1912                }
1913
1914
1915                function display_status($user_status)
1916                {
1917                        if(@$this->prefs['calendar']['display_status'] && $user_status)
1918                        {
1919                                $user_status = substr($this->get_long_status($user_status),0,1);
1920
1921                                return ' ('.$user_status.')';
1922                        }
1923                        else
1924                        {
1925                                return '';
1926                        }
1927                }
1928
1929                function get_long_status($status_short)
1930                {
1931                        switch ($status_short)
1932                        {
1933                                case 'A':
1934                                        $status = lang('Accepted');
1935                                        break;
1936                                case 'R':
1937                                        $status = lang('Rejected');
1938                                        break;
1939                                case 'T':
1940                                        $status = lang('Tentative');
1941                                        break;
1942                                case 'U':
1943                                        $status = lang('No Response');
1944                                        break;
1945                        }
1946                        return $status;
1947                }
1948
1949                function is_private($event,$owner)
1950                {
1951                        if($owner == 0)
1952                        {
1953                                $owner = $this->owner;
1954                        }
1955                        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'])
1956                        {
1957                                return False;
1958                        }
1959                        elseif($event['public'] == 0)
1960                        {
1961                                return True;
1962                        }
1963                        elseif($event['public'] == 2)
1964                        {
1965                                $is_private = True;
1966                                $groups = $GLOBALS['phpgw']->accounts->membership($owner);
1967                                while (list($key,$group) = each($groups))
1968                                {
1969                                        if (strpos(' '.implode(',',$event['groups']).' ',$group['account_id']))
1970                                        {
1971                                                return False;
1972                                        }
1973                                }
1974                        }
1975                        else
1976                        {
1977                                return False;
1978                        }
1979
1980                        return $is_private;
1981                }
1982
1983                function get_short_field($event,$is_private=True,$field='')
1984                {
1985                        if($is_private && $event['type'] == 'E')
1986                        {
1987                                return lang('Restrict');
1988                        }
1989                        else if($is_private && $event['type'] == 'P')
1990                        {
1991                                return lang('private');
1992                        }
1993
1994// cut off too long titles
1995                        elseif(strlen($event[$field]) > 19 && !$this->printer_friendly && $field=="title")
1996//                      elseif(strlen($event[$field]) > 19 && $this->printer_friendly)
1997                        {
1998// we dont use currently 160304
1999//                              return substr($event[$field], 0 , 19) . '&nbsp;...';
2000                                return $event[$field];
2001                        }
2002                        else
2003                        {
2004                                return $event[$field];
2005                        }
2006                }
2007
2008                function long_date($first,$last=0)
2009                {
2010                        if (!is_array($first))
2011                        {
2012                                $first = $this->time2array($raw = $first);
2013                                $first['raw'] = $raw;
2014                                $first['day'] = $first['mday'];
2015                        }
2016                        if ($last && !is_array($last))
2017                        {
2018                                $last = $this->time2array($raw = $last);
2019                                $last['raw'] = $raw;
2020                                $last['day'] = $last['mday'];
2021                        }
2022                        $datefmt = $this->prefs['common']['dateformat'];
2023
2024                        $month_before_day = strtolower($datefmt[0]) == 'm' ||
2025                                strtolower($datefmt[2]) == 'm' && $datefmt[4] == 'd';
2026
2027                        for ($i = 0; $i < 5; $i += 2)
2028                        {
2029                                switch($datefmt[$i])
2030                                {
2031                                        case 'd':
2032                                                $range .= $first['day'] . ($datefmt[1] == '.' ? '.' : '');
2033                                                if ($first['month'] != $last['month'] || $first['year'] != $last['year'])
2034                                                {
2035                                                        if (!$month_before_day)
2036                                                        {
2037                                                                $range .= ' '.lang(strftime('%B',$first['raw']));
2038                                                        }
2039                                                        if ($first['year'] != $last['year'] && $datefmt[0] != 'Y')
2040                                                        {
2041                                                                $range .= ($datefmt[0] != 'd' ? ', ' : ' ') . $first['year'];
2042                                                        }
2043                                                        if (!$last)
2044                                                        {
2045                                                                return $range;
2046                                                        }
2047                                                        $range .= ' - ';
2048
2049                                                        if ($first['year'] != $last['year'] && $datefmt[0] == 'Y')
2050                                                        {
2051                                                                $range .= $last['year'] . ', ';
2052                                                        }
2053
2054                                                        if ($month_before_day)
2055                                                        {
2056                                                                $range .= lang(strftime('%B',$last['raw']));
2057                                                        }
2058                                                }
2059                                                else
2060                                                {
2061                                                        $range .= ' - ';
2062                                                }
2063                                                $range .= ' ' . $last['day'] . ($datefmt[1] == '.' ? '.' : '');
2064                                                break;
2065                                        case 'm':
2066                                        case 'M':
2067                                                $range .= ' '.lang(strftime('%B',$month_before_day ? $first['raw'] : $last['raw'])) . ' ';
2068                                                break;
2069                                        case 'Y':
2070                                                $range .= ($datefmt[0] == 'm' ? ', ' : ' ') . ($datefmt[0] == 'Y' ? $first['year'].($datefmt[2] == 'd' ? ', ' : ' ') : $last['year'].' ');
2071                                                break;
2072                                }
2073                        }
2074                        return $range;
2075                }
2076
2077                function get_week_label()
2078                {
2079                        $first = $GLOBALS['phpgw']->datetime->gmtdate($GLOBALS['phpgw']->datetime->get_weekday_start($this->year, $this->month, $this->day));
2080                        $last = $GLOBALS['phpgw']->datetime->gmtdate($first['raw'] + 518400);
2081
2082                        return ($this->long_date($first,$last));
2083                }
2084
2085                function normalizeminutes(&$minutes)
2086                {
2087                        $hour = 0;
2088                        $min = (int)$minutes;
2089                        if($min >= 60)
2090                        {
2091                                $hour += $min / 60;
2092                                $min %= 60;
2093                        }
2094                        settype($minutes,'integer');
2095                        $minutes = $min;
2096                        return $hour;
2097                }
2098
2099                function splittime($time,$follow_24_rule=True)
2100                {
2101                        $temp = array('hour','minute','second','ampm');
2102                        $time = strrev($time);
2103                        $second = (int)(strrev(substr($time,0,2)));
2104                        $minute = (int)(strrev(substr($time,2,2)));
2105                        $hour   = (int)(strrev(substr($time,4)));
2106                        $hour += $this->normalizeminutes($minute);
2107                        $temp['second'] = $second;
2108                        $temp['minute'] = $minute;
2109                        $temp['hour']   = $hour;
2110                        $temp['ampm']   = '  ';
2111                        if($follow_24_rule == True)
2112                        {
2113                                if ($this->prefs['common']['timeformat'] == '24')
2114                                {
2115                                        return $temp;
2116                                }
2117
2118                                $temp['ampm'] = 'am';
2119
2120                                if ((int)$temp['hour'] > 12)
2121                                {
2122                                        $temp['hour'] = (int)((int)$temp['hour'] - 12);
2123                                        $temp['ampm'] = 'pm';
2124                                }
2125                                elseif ((int)$temp['hour'] == 12)
2126                                {
2127                                        $temp['ampm'] = 'pm';
2128                                }
2129                        }
2130                        return $temp;
2131                }
2132
2133                function get_exception_array($exception_str='')
2134                {
2135                        $exception = Array();
2136                        if(strpos(' '.$exception_str,','))
2137                        {
2138                                $exceptions = explode(',',$exception_str);
2139                                for($exception_count=0;$exception_count<count($exceptions);$exception_count++)
2140                                {
2141                                        $exception[] = (int)$exceptions[$exception_count];
2142                                }
2143                        }
2144                        elseif($exception_str != '')
2145                        {
2146                                $exception[] = (int)$exception_str;
2147                        }
2148                        return $exception;
2149                }
2150
2151                function build_time_for_display($fixed_time)
2152                {
2153                        $time = $this->splittime($fixed_time);
2154                        $str = $time['hour'].':'.((int)$time['minute']<=9?'0':'').$time['minute'];
2155
2156                        if ($this->prefs['common']['timeformat'] == '12')
2157                        {
2158                                $str .= ' ' . $time['ampm'];
2159                        }
2160
2161                        return $str;
2162                }
2163
2164                function sort_event($event,$date)
2165                {
2166                        $inserted = False;
2167                        if(isset($event['recur_exception']))
2168                        {
2169                                $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;
2170                                while($inserted == False && list($key,$exception_time) = each($event['recur_exception']))
2171                                {
2172                                        if($this->debug)
2173                                        {
2174                                                echo '<!-- checking exception datetime '.$exception_time.' to event datetime '.$event_time.' -->'."\n";
2175                                        }
2176                                        if($exception_time == $event_time)
2177                                        {
2178                                                $inserted = True;
2179                                        }
2180                                }
2181                        }
2182                        if($this->cached_events[$date] && $inserted == False)
2183                        {
2184
2185                                if($this->debug)
2186                                {
2187                                        echo '<!-- Cached Events found for '.$date.' -->'."\n";
2188                                }
2189                                $year = substr($date,0,4);
2190                                $month = substr($date,4,2);
2191                                $day = substr($date,6,2);
2192
2193                                if($this->debug)
2194                                {
2195                                        echo '<!-- Date : '.$date.' Count : '.count($this->cached_events[$date]).' -->'."\n";
2196                                }
2197
2198                                for($i=0;$i<count($this->cached_events[$date]);$i++)
2199                                {
2200                                        if($this->cached_events[$date][$i]['id'] == $event['id'] || $this->cached_events[$date][$i]['reference'] == $event['id'])
2201                                        {
2202                                                if($this->debug)
2203                                                {
2204                                                        echo '<!-- Item already inserted! -->'."\n";
2205                                                }
2206                                                $inserted = True;
2207                                                break;
2208                                        }
2209                                        /* This puts all spanning events across multiple days up at the top. */
2210                                        if($this->cached_events[$date][$i]['recur_type'] == MCAL_RECUR_NONE)
2211                                        {
2212                                                if($this->cached_events[$date][$i]['start']['mday'] != $day && $this->cached_events[$date][$i]['end']['mday'] >= $day)
2213                                                {
2214                                                        continue;
2215                                                }
2216                                        }
2217                                        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)))
2218                                        {
2219                                                for($j=count($this->cached_events[$date]);$j>=$i;$j--)
2220                                                {
2221                                                        $this->cached_events[$date][$j] = $this->cached_events[$date][$j-1];
2222                                                }
2223                                                if($this->debug)
2224                                                {
2225                                                        echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
2226                                                }
2227                                                $inserted = True;
2228                                                $this->cached_events[$date][$i] = $event;
2229                                                break;
2230                                        }
2231                                }
2232                        }
2233                        if(!$inserted)
2234                        {
2235                                if($this->debug)
2236                                {
2237                                        echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
2238                                }
2239                                $this->cached_events[$date][] = $event;
2240                        }
2241                }
2242
2243                function check_repeating_events($datetime)
2244                {
2245                        @reset($this->repeating_events);
2246                        $search_date_full = date('Ymd',$datetime);
2247                        $search_date_year = date('Y',$datetime);
2248                        $search_date_month = date('m',$datetime);
2249                        $search_date_day = date('d',$datetime);
2250                        $search_date_dow = date('w',$datetime);
2251                        $search_beg_day = mktime(0,0,0,$search_date_month,$search_date_day,$search_date_year);
2252                        if($this->debug)
2253                        {
2254                                echo '<!-- Search Date Full = '.$search_date_full.' -->'."\n";
2255                        }
2256                        $repeated = $this->repeating_events;
2257                        $r_events = count($repeated);
2258                        for ($i=0;$i<$r_events;$i++)
2259                        {
2260                                $rep_events = $this->repeating_events[$i];
2261                                $id = $rep_events['id'];
2262                                $event_beg_day = mktime(0,0,0,$rep_events['start']['month'],$rep_events['start']['mday'],$rep_events['start']['year']);
2263                                if($rep_events['recur_enddate']['month'] != 0 && $rep_events['recur_enddate']['mday'] != 0 && $rep_events['recur_enddate']['year'] != 0)
2264                                {
2265                                        $event_recur_time = $this->maketime($rep_events['recur_enddate']);
2266                                }
2267                                else
2268                                {
2269                                        $event_recur_time = mktime(0,0,0,1,1,2030);
2270                                }
2271                                $end_recur_date = date('Ymd',$event_recur_time);
2272                                $full_event_date = date('Ymd',$event_beg_day);
2273
2274                                if($this->debug)
2275                                {
2276                                        echo '<!-- check_repeating_events - Processing ID - '.$id.' -->'."\n";
2277                                        echo '<!-- check_repeating_events - Recurring End Date - '.$end_recur_date.' -->'."\n";
2278                                }
2279
2280                                // only repeat after the beginning, and if there is an rpt_end before the end date
2281                                if (($search_date_full > $end_recur_date) || ($search_date_full < $full_event_date))
2282                                {
2283                                        continue;
2284                                }
2285
2286                                if ($search_date_full == $full_event_date)
2287                                {
2288                                        $this->sort_event($rep_events,$search_date_full);
2289                                        continue;
2290                                }
2291                                else
2292                                {
2293                                        $freq = $rep_events['recur_interval'];
2294                                        $freq = $freq ? $freq : 1;
2295                                        $type = $rep_events['recur_type'];
2296                                        switch($type)
2297                                        {
2298                                                case MCAL_RECUR_DAILY:
2299                                                        if($this->debug)
2300                                                        {
2301                                                                echo '<!-- check_repeating_events - MCAL_RECUR_DAILY - '.$id.' -->'."\n";
2302                                                        }
2303                                                       
2304                                                        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)
2305                                                        {
2306                                                                $this->sort_event($rep_events,$search_date_full);
2307                                                        }
2308                                                        elseif (floor(($search_beg_day - $event_beg_day)/86400) % ($freq ? $freq : 1))
2309                                                        {
2310                                                                continue;
2311                                                        }
2312                                                        else
2313                                                        {
2314                                                                $this->sort_event($rep_events,$search_date_full);
2315                                                        }
2316                                                        break;
2317                                                case MCAL_RECUR_WEEKLY:
2318                                                        if ((floor($search_beg_day / 604800) - floor($event_beg_day / 604800)) % $freq)
2319                                                        {
2320                                                                continue;
2321                                                        }
2322                                                        $check = 0;
2323                                                        switch($search_date_dow)
2324                                                        {
2325                                                                case 0:
2326                                                                        $check = MCAL_M_SUNDAY;
2327                                                                        break;
2328                                                                case 1:
2329                                                                        $check = MCAL_M_MONDAY;
2330                                                                        break;
2331                                                                case 2:
2332                                                                        $check = MCAL_M_TUESDAY;
2333                                                                        break;
2334                                                                case 3:
2335                                                                        $check = MCAL_M_WEDNESDAY;
2336                                                                        break;
2337                                                                case 4:
2338                                                                        $check = MCAL_M_THURSDAY;
2339                                                                        break;
2340                                                                case 5:
2341                                                                        $check = MCAL_M_FRIDAY;
2342                                                                        break;
2343                                                                case 6:
2344                                                                        $check = MCAL_M_SATURDAY;
2345                                                                        break;
2346                                                        }
2347                                                        if ($rep_events['recur_data'] & $check)
2348                                                        {
2349                                                                $this->sort_event($rep_events,$search_date_full);
2350                                                        }
2351                                                        break;
2352                                                case MCAL_RECUR_MONTHLY_WDAY:
2353                                                        if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month']) % $freq)
2354                                                        {
2355                                                                continue;
2356                                                        }
2357
2358                                                        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)) &&
2359                                                                (ceil($rep_events['start']['mday']/7) == ceil($search_date_day/7)))
2360                                                        {
2361                                                                $this->sort_event($rep_events,$search_date_full);
2362                                                        }
2363                                                        break;
2364                                                case MCAL_RECUR_MONTHLY_MDAY:
2365                                                        if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month'])  % ($freq ? $freq : 1))
2366                                                        {
2367                                                                continue;
2368                                                        }
2369                                                        if ($search_date_day == $rep_events['start']['mday'])
2370                                                        {
2371                                                                $this->sort_event($rep_events,$search_date_full);
2372                                                        }
2373                                                        break;
2374                                                case MCAL_RECUR_YEARLY:
2375                                                        if (($search_date_year - $rep_events['start']['year']) % ($freq ? $freq : 1))
2376                                                        {
2377                                                                continue;
2378                                                        }
2379                                                        if (date('dm',$datetime) == date('dm',$event_beg_day))
2380                                                        {
2381                                                                $this->sort_event($rep_events,$search_date_full);
2382                                                        }
2383                                                        break;
2384                                        }
2385                                }
2386                        }       // end for loop
2387                }       // end function
2388
2389                function store_to_cache($params)
2390                {
2391                        if(!is_array($params))
2392                        {
2393                                return False;
2394                        }
2395                        if (isset($params['start']) && ($datearr = $GLOBALS['server']->iso86012date($params['start'])))
2396                        {
2397                                $syear = $datearr['year'];
2398                                $smonth = $datearr['month'];
2399                                $sday = $datearr['mday'];
2400                                $this->xmlrpc = True;
2401                        }
2402                        else
2403                        {
2404                                $syear = $params['syear'];
2405                                $smonth = $params['smonth'];
2406                                $sday = $params['sday'];
2407                        }
2408                        if (isset($params['end']) && ($datearr = $GLOBALS['server']->iso86012date($params['end'])))
2409                        {
2410                                $eyear = $datearr['year'];
2411                                $emonth = $datearr['month'];
2412                                $eday = $datearr['mday'];
2413                                $this->xmlrpc = True;
2414                        }
2415                        else
2416                        {
2417                                $eyear = (isset($params['eyear'])?$params['eyear']:0);
2418                                $emonth = (isset($params['emonth'])?$params['emonth']:0);
2419                                $eday = (isset($params['eday'])?$params['eday']:0);
2420                        }
2421                        if (!isset($params['owner']) && @$this->xmlrpc)
2422                        {
2423                                $owner_id = $GLOBALS['phpgw_info']['user']['user_id'];
2424                        }
2425                        else
2426                        {
2427                                $owner_id = (isset($params['owner'])?$params['owner']:0);
2428                                if($owner_id==0 && $this->is_group)
2429                                {
2430                                        unset($owner_id);
2431                                        $owner_id = $this->g_owner;
2432                                        if($this->debug)
2433                                        {
2434                                                echo '<!-- owner_id in ('.implode(',',$owner_id).') -->'."\n";
2435                                        }
2436                                }
2437                        }
2438                        if(!$eyear && !$emonth && !$eday)
2439                        {
2440                                $edate = mktime(23,59,59,$smonth + 1,$sday + 1,$syear);
2441                                $eyear = date('Y',$edate);
2442                                $emonth = date('m',$edate);
2443                                $eday = date('d',$edate);
2444                        }
2445                        else
2446                        {
2447                                if(!$eyear)
2448                                {
2449                                        $eyear = $syear;
2450                                }
2451                                //Tratamento do valor final (mes) da pesquisa de eventos feita em $this->so->list_events.
2452                                //Se $emonth nao tem valor, recebe o valor de $smonth (que recebe $params['smonth']) e soma 1.
2453                                //O valor $params['emonth'] indica o mes final para a pesquisa de eventos, e passou a ser
2454                                //informado na a impressao de eventos mensais. Mudancas feitas em class.uicalendar.inc.php,
2455                                //function display_month_print();
2456                                if(!$emonth)
2457                                {
2458                                        $emonth = $smonth + 1;
2459                                        if($emonth > 12)
2460                                        {
2461                                                $emonth = 1;
2462                                                $eyear++;
2463                                        }
2464                                }
2465                                if(!$eday)
2466                                {
2467                                        $eday = $sday + 1;
2468                                }
2469                                $edate = mktime(23,59,59,$emonth,$eday,$eyear);
2470                        }
2471                        //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";
2472                        if($this->debug)
2473                        {
2474                                echo '<!-- Start Date : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2475                                echo '<!-- End   Date : '.sprintf("%04d%02d%02d",$eyear,$emonth,$eday).' -->'."\n";
2476                        }
2477                        //A variavel $month_print recebe o parametro 'saux' com o mes de inicio da pesquisa de eventos por
2478                        //$this->so->list_events. O valor do mes final da pesquisa e tratado no codigo acima;
2479                        //$month_ini = $params['saux'];
2480
2481                        if($owner_id)
2482                        {
2483                                $cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
2484                                $cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
2485                        }
2486                        else
2487                        {
2488                                $cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
2489                                $cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
2490                        }
2491
2492                        $c_cached_ids = count($cached_event_ids);
2493                        $c_cached_ids_repeating = count($cached_event_ids_repeating);
2494
2495                        if($this->debug)
2496                        {
2497                                echo '<!-- events cached : '.$c_cached_ids.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2498                                echo '<!-- repeating events cached : '.$c_cached_ids_repeating.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
2499                        }
2500
2501                        $this->cached_events = Array();
2502
2503                        if($c_cached_ids == 0 && $c_cached_ids_repeating == 0)
2504                        {
2505                                return;
2506                        }
2507
2508                        $cache_start = (int)(sprintf("%04d%02d%02d",$syear,$smonth,$sday));
2509                        $cached_event=$this->get_cached_event();
2510                        if($c_cached_ids)
2511                        {
2512                                for($i=0;$i<$c_cached_ids;$i++)
2513                                {
2514                                        $event = $this->so->read_entry($cached_event_ids[$i]);
2515                                        if ($event['recur_type'])
2516                                        {
2517                                                continue;       // fetch recuring events only in 2. loop
2518                                        }
2519                                        $startdate = (int)(date('Ymd',$this->maketime($event['start'])));
2520                                        $enddate = (int)(date('Ymd',$this->maketime($event['end'])));
2521                                        $this->cached_events[$startdate][] = $event;
2522                                        if($startdate != $enddate)
2523                                        {
2524                                                $start['year'] = (int)(substr($startdate,0,4));
2525                                                $start['month'] = (int)(substr($startdate,4,2));
2526                                                $start['mday'] = (int)(substr($startdate,6,2));
2527                                                for($j=$startdate,$k=0;$j<=$enddate;$k++,$j=(int)(date('Ymd',mktime(0,0,0,$start['month'],$start['mday'] + $k,$start['year']))))
2528                                                {
2529                                                        $c_evt_day = count($this->cached_events[$j]) - 1;
2530                                                        if($c_evt_day < 0)
2531                                                        {
2532                                                                $c_evt_day = 0;
2533                                                        }
2534                                                        if($this->debug)
2535                                                        {
2536                                                                echo '<!-- Date: '.$j.' Count : '.$c_evt_day.' -->'."\n";
2537                                                        }
2538                                                        if($this->cached_events[$j][$c_evt_day]['id'] != $event['id'])
2539                                                        {
2540                                                                if($this->debug)
2541                                                                {
2542                                                                        echo '<!-- Adding Event for Date: '.$j.' -->'."\n";
2543                                                                }
2544                                                                $this->cached_events[$j][] = $event;
2545                                                        }
2546                                                        if ($j >= $cache_start && (@$params['no_doubles'] || @$this->xmlrpc))
2547                                                        {
2548                                                                break;  // add event only once on it's startdate
2549                                                        }
2550                                                }
2551                                        }
2552                                }
2553                        }
2554
2555                        $this->repeating_events = Array();
2556                        if($c_cached_ids_repeating)
2557                        {
2558                                for($i=0;$i<$c_cached_ids_repeating;$i++)
2559                                {
2560                                        $this->repeating_events[$i] = $this->so->read_entry($cached_event_ids_repeating[$i]);
2561                                        if($this->debug)
2562                                        {
2563                                                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";
2564                                        }
2565                                }
2566                                for($date=mktime(0,0,0,$smonth,$sday,$syear);$date<=$edate;$date += 86400)
2567                                {
2568                                        if($this->debug)
2569                                        {
2570                                                $search_date = date('Ymd',$date);
2571                                                echo '<!-- Calling check_repeating_events('.$search_date.') -->'."\n";
2572                                        }
2573                                        $this->check_repeating_events($date);
2574                                        if($this->debug)
2575                                        {
2576                                                echo '<!-- Total events found matching '.$search_date.' = '.count($this->cached_events[$search_date]).' -->'."\n";
2577                                                for($i=0;$i<count($this->cached_events[$search_date]);$i++)
2578                                                {
2579                                                        echo '<!-- Date: '.$search_date.' ['.$i.'] = '.$this->cached_events[$search_date][$i]['id'].' -->'."\n";
2580                                                }
2581                                        }
2582                                }
2583                        }
2584                        $retval = Array();
2585                        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)))
2586                        {
2587                                if(is_array($this->cached_events[$j]))
2588                                {
2589                                        if ($this->xmlrpc)
2590                                        {
2591                                                foreach($this->cached_events[$j] as $event)
2592                                                {
2593                                                        $retval[] = $this->xmlrpc_prepare($event);
2594                                                }
2595                                        }
2596                                        else
2597                                        {
2598                                                $retval[$j] = $this->cached_events[$j];
2599                                        }
2600                                }
2601                        }
2602                        //echo "store_to_cache(".print_r($params,True).")=<pre>".print_r($retval,True)."</pre>\n";
2603                        $this->so->cal->event = $cached_event;
2604                        return $retval;
2605                }
2606
2607                function xmlrpc_prepare(&$event)
2608                {
2609                        $event['rights'] = $this->grants[$event['owner']];
2610
2611                        foreach(array('start','end','modtime','recur_enddate') as $name)
2612                        {
2613                                if (isset($event[$name]))
2614                                {
2615                                        $event[$name] = $GLOBALS['server']->date2iso8601($event[$name]);
2616                                }
2617                        }
2618                        if (is_array($event['recur_exception']))
2619                        {
2620                                foreach($event['recur_exception'] as $key => $timestamp)
2621                                {
2622                                        $event['recur_exception'][$key] = $GLOBALS['server']->date2iso8601($timestamp);
2623                                }
2624                        }
2625                        static $user_cache = array();
2626
2627                        if (!is_object($GLOBALS['phpgw']->perferences))
2628                        {
2629                                $GLOBALS['phpgw']->perferences = CreateObject('phpgwapi.preferences');
2630                        }
2631                        foreach($event['participants'] as $user_id => $status)
2632                        {
2633                                if (!isset($user_cache[$user_id]))
2634                                {
2635                                        $user_cache[$user_id] = array(
2636                                                'name'   => $GLOBALS['phpgw']->common->grab_owner_name($user_id),
2637                                                'email'  => $GLOBALS['phpgw']->perferences->email_address($user_id)
2638                                        );
2639                                }
2640                                $event['participants'][$user_id] = $user_cache[$user_id] + array(
2641                                        'status' => $status,
2642                                );
2643                        }
2644                        if (is_array($event['alarm']))
2645                        {
2646                                foreach($event['alarm'] as $id => $alarm)
2647                                {
2648                                        $event['alarm'][$id]['time'] = $GLOBALS['server']->date2iso8601($alarm['time']);
2649                                        if ($alarm['owner'] != $GLOBALS['phpgw_info']['user']['account_id'])
2650                                        {
2651                                                unset($event['alarm'][$id]);
2652                                        }
2653                                }
2654                        }
2655                        $event['category'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$event['category']));
2656
2657                        // using access={public|privat} in all modules via xmlrpc
2658                        $event['access'] = $event['public'] ? 'public' : 'privat';
2659                        unset($event['public']);
2660
2661                        return $event;
2662                }
2663
2664                /* Begin Appsession Data */
2665                function store_to_appsession($event)
2666                {
2667                        $GLOBALS['phpgw']->session->appsession('entry','calendar',$event);
2668                }
2669
2670                function restore_from_appsession()
2671                {
2672                        $this->event_init();
2673                        $event = $GLOBALS['phpgw']->session->appsession('entry','calendar');
2674                        $this->so->cal->event = $event;
2675                        return $event;
2676                }
2677                /* End Appsession Data */
2678
2679                /* Begin of SO functions */
2680                function get_cached_event()
2681                {
2682                        return $this->so->get_cached_event();
2683                }
2684
2685                function add_attribute($var,$value,$index='**(**')
2686                {
2687                        $this->so->add_attribute($var,$value,$index);
2688                }
2689
2690                function event_init()
2691                {
2692                        $this->so->event_init();
2693                }
2694
2695                function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
2696                {
2697                        $this->so->set_start($year,$month,$day,$hour,$min,$sec);
2698                }
2699
2700                function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
2701                {
2702                        $this->so->set_end($year,$month,$day,$hour,$min,$sec);
2703                }
2704
2705                function set_title($title='')
2706                {
2707                        $this->so->set_title($title);
2708                }
2709
2710                function set_description($description='')
2711                {
2712                        $this->so->set_description($description);
2713                }
2714                function set_ex_participants($ex_participants='')
2715                {
2716                        $this->so->set_ex_participants($ex_participants);
2717                }
2718
2719                function set_class($class)
2720                {
2721                        $this->so->set_class($class);
2722                }
2723
2724                function set_category($category='')
2725                {
2726                        $this->so->set_category($category);
2727                }
2728
2729                function set_alarm($alarm)
2730                {
2731                        $this->so->set_alarm($alarm);
2732                }
2733
2734                function set_recur_none()
2735                {
2736                        $this->so->set_recur_none();
2737                }
2738
2739                function set_recur_daily($year,$month,$day,$interval)
2740                {
2741                        $this->so->set_recur_daily($year,$month,$day,$interval);
2742                }
2743
2744                function set_recur_weekly($year,$month,$day,$interval,$weekdays)
2745                {
2746                        $this->so->set_recur_weekly($year,$month,$day,$interval,$weekdays);
2747                }
2748
2749                function set_recur_monthly_mday($year,$month,$day,$interval)
2750                {
2751                        $this->so->set_recur_monthly_mday($year,$month,$day,$interval);
2752                }
2753
2754                function set_recur_monthly_wday($year,$month,$day,$interval)
2755                {
2756                        $this->so->set_recur_monthly_wday($year,$month,$day,$interval);
2757                }
2758
2759                function set_recur_yearly($year,$month,$day,$interval)
2760                {
2761                        $this->so->set_recur_yearly($year,$month,$day,$interval);
2762                }
2763                /* End of SO functions */
2764
2765                function prepare_matrix($interval,$increment,$part,$fulldate)
2766                {
2767                        for($h=0;$h<24;$h++)
2768                        {
2769                                for($m=0;$m<$interval;$m++)
2770                                {
2771                                        $index = (($h * 10000) + (($m * $increment) * 100));
2772                                        $time_slice[$index]['marker'] = '&nbsp';
2773                                        $time_slice[$index]['description'] = '';
2774                                }
2775                        }
2776                        foreach($this->cached_events[$fulldate] as $event)
2777                        {
2778                                if ($event['participants'][$part] == 'R')
2779                                {
2780                                        continue;       // dont show rejected invitations, as they are free time
2781                                }
2782                                $eventstart = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset);
2783                                $eventend = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset);
2784                                $start = ($eventstart['hour'] * 10000) + ($eventstart['minute'] * 100);
2785                                $starttemp = $this->splittime("$start",False);
2786                                $subminute = 0;
2787                                for($m=0;$m<$interval;$m++)
2788                                {
2789                                        $minutes = $increment * $m;
2790                                        if((int)$starttemp['minute'] > $minutes && (int)$starttemp['minute'] < ($minutes + $increment))
2791                                        {
2792                                                $subminute = ($starttemp['minute'] - $minutes) * 100;
2793                                        }
2794                                }
2795                                $start -= $subminute;
2796                                $end =  ($eventend['hour'] * 10000) + ($eventend['minute'] * 100);
2797                                $endtemp = $this->splittime("$end",False);
2798                                $addminute = 0;
2799                                for($m=0;$m<$interval;$m++)
2800                                {
2801                                        $minutes = ($increment * $m);
2802                                        if($endtemp['minute'] < ($minutes + $increment) && $endtemp['minute'] > $minutes)
2803                                        {
2804                                                $addminute = ($minutes + $increment - $endtemp['minute']) * 100;
2805                                        }
2806                                }
2807                                $end += $addminute;
2808                                $starttemp = $this->splittime("$start",False);
2809                                $endtemp = $this->splittime("$end",False);
2810
2811                                for($h=$starttemp['hour'];$h<=$endtemp['hour'];$h++)
2812                                {
2813                                        $startminute = 0;
2814                                        $endminute = $interval;
2815                                        $hour = $h * 10000;
2816                                        if($h == (int)$starttemp['hour'])
2817                                        {
2818                                                $startminute = ($starttemp['minute'] / $increment);
2819                                        }
2820                                        if($h == (int)$endtemp['hour'])
2821                                        {
2822                                                $endminute = ($endtemp['minute'] / $increment);
2823                                        }
2824                                        $private = $this->is_private($event,$part);
2825                                        $time_display = $GLOBALS['phpgw']->common->show_date($eventstart['raw'],$this->users_timeformat).'-'.$GLOBALS['phpgw']->common->show_date($eventend['raw'],$this->users_timeformat);
2826                                        $time_description = '('.$time_display.') '.$this->get_short_field($event,$private,'title').$this->display_status($event['participants'][$part]);
2827                                        for($m=$startminute;$m<$endminute;$m++)
2828                                        {
2829                                                $index = ($hour + (($m * $increment) * 100));
2830                                                $time_slice[$index]['marker'] = '-';
2831                                                $time_slice[$index]['description'] = $time_description;
2832                                                $time_slice[$index]['id'] = $event['id'];
2833                                        }
2834                                }
2835                        }
2836                        return $time_slice;
2837                }
2838
2839                /*!
2840                @function set_status
2841                @abstract set the participant response $status for event $cal_id and notifies the owner of the event
2842                */
2843                function set_status($cal_id,$status,$user = false)
2844                {
2845                        $status2msg = array(
2846                                REJECTED  => MSG_REJECTED,
2847                                TENTATIVE => MSG_TENTATIVE,
2848                                ACCEPTED  => MSG_ACCEPTED
2849                        );
2850                        if (!isset($status2msg[$status]))
2851                        {
2852                                return False;
2853                        }
2854                        $event = $this->so->read_entry($cal_id);
2855                        if($user) $account_id = $user;
2856                        else $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
2857                        if(($status2msg[$status] == "5" && $event['participants'][$account_id] == "A") ||
2858                         ($status2msg[$status] == "3" && $event['participants'][$account_id] == "R")) {
2859                                return True;
2860                        }
2861                        $this->so->set_status($cal_id,$status,$account_id);
2862                        $event = $this->so->read_entry($cal_id);
2863                        $this->send_update($status2msg[$status],$event['participants'],$event,false,$account_id);
2864
2865                        $sts = array_values( $event['participants'] );
2866
2867                        //verifica se todos os participantes rejeitaram o evento
2868                        while( $sts[0] && $sts[0] === 'R' ) array_pop( $sts );
2869
2870                        if( empty( $sts ) )
2871                        {
2872                                $this->so->delete_entry( $cal_id );
2873                                $this->so->expunge();
2874                        }
2875                }
2876
2877                /*!
2878                @function update_requested
2879                @abstract checks if $userid has requested (in $part_prefs) updates for $msg_type
2880                @syntax update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2881                @param $userid numerical user-id
2882                @param $part_prefs preferces of the user $userid
2883                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
2884                @param $old_event Event before the change
2885                @param $new_event Event after the change
2886                @returns 0 = no update requested, > 0 update requested
2887                */
2888                function update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
2889                {
2890                        if ($msg_type == MSG_ALARM)
2891                        {
2892                                return True;    // always True for now
2893                        }
2894                        $want_update = 0;
2895
2896                        // the following switch fall-through all cases, as each included the following too
2897                        //
2898                        $msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE;
2899
2900                        switch($ru = $part_prefs['calendar']['receive_updates'])
2901                        {
2902                                case 'responses':
2903                                        if ($msg_is_response)
2904                                        {
2905                                                ++$want_update;
2906                                        }
2907                                case 'modifications':
2908                                        if ($msg_type == MSG_MODIFIED)
2909                                        {
2910                                                ++$want_update;
2911                                        }
2912                                case 'time_change_4h':
2913                                case 'time_change':
2914                                        $diff = max(abs($this->maketime($old_event['start'])-$this->maketime($new_event['start'])),
2915                                                abs($this->maketime($old_event['end'])-$this->maketime($new_event['end'])));
2916                                        $check = $ru == 'time_change_4h' ? 4 * 60 * 60 - 1 : 0;
2917                                        if ($msg_type == MSG_MODIFIED && $diff > $check)
2918                                        {
2919                                                ++$want_update;
2920                                        }
2921                                case 'add_cancel':
2922                                        if ($old_event['owner'] == $userid && $msg_is_response ||
2923                                                $msg_type == MSG_DELETED || $msg_type == MSG_ADDED)
2924                                        {
2925                                                ++$want_update;
2926                                        }
2927                                        break;
2928                                case 'no':
2929                                        break;
2930                        }
2931                        //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";
2932                        return $want_update > 0;
2933                }
2934
2935
2936                function create_vcard($event_arrays , $metodo = 'PUBLISH', $externo = false,$importAccount = false)
2937                {
2938                    if(!$importAccount)
2939                        $importAccount['mail'] = $GLOBALS['phpgw_info']['user']['email'];
2940
2941                    if(!is_array($event_arrays))
2942                                return null;
2943
2944                    $tmpattach="BEGIN:VCALENDAR\r\n"
2945                        ."PRODID:-//Expresso Livre//Calendar//EN\r\n"
2946                        ."VERSION:2.0\r\n"
2947                        ."CALSCALE:GREGORIAN\r\n"
2948                        ."METHOD:".$metodo."\r\n";
2949
2950                    //$offset = ((int)substr(date('O',$GLOBALS['phpgw']->datetime->users_localtime), 0, 3));
2951                   
2952                    //Recupera o offset do cliente com base na diferenca entre o horario do cliente (timezone da preferencia)
2953                    //e o unixtime
2954                    //$offset = ((($GLOBALS['phpgw']->datetime->users_localtime) -  ($GLOBALS['phpgw']->datetime->gmtnow))/60)/60;
2955                   
2956                        $timezone = date('e');
2957
2958                        foreach ($event_arrays as $event_array)
2959                        {
2960                            $sy = $event_array['start']['year'];
2961                            $sm = $event_array['start']['month'];
2962                            $sd = $event_array['start']['mday'];
2963                            $sh = $event_array['start']['hour'];
2964                            $sn = $event_array['start']['min'];
2965                            $dtstart = sprintf("%04d%02d%02dT%02d%02d00", $sy, $sm, $sd, $sh, $sn);
2966
2967                            $ey = $event_array['end']['year'];
2968                            $em = $event_array['end']['month'];
2969                            $ed = $event_array['end']['mday'];
2970                            $eh = $event_array['end']['hour'];
2971                            $en = $event_array['end']['min'];
2972                            $dtend = sprintf("%04d%02d%02dT%02d%02d00", $ey, $em, $ed, $eh, $en);
2973
2974                            // Necessário espaços após quebra-de-linha, na descrição, caso contrário
2975                            // ocorrerá erro ao importar o agendamento no Outlook (erro lunar).
2976                            $description = str_replace("\n","\n ",$event_array['description']);
2977                            $tmpattach.="BEGIN:VEVENT\r\n";
2978                                                       
2979                            if(isset($event_array['organizer']) && $event_array['owner'] != -2)
2980                            {
2981                                $ldap = $this->getLdap(); 
2982                                $justthese = array("mail","cn");
2983                                $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$event_array['owner']."))";
2984                                $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
2985                                $entry = ldap_get_entries($ldap, $search);                                       
2986                                        $organizer = 'ORGANIZER;CN='.$entry[0]['cn'][0].':mailto:'.$entry[0]['mail'][0]."\r\n";
2987                                }   
2988                                else{   
2989                                        $email = explode('&lt;', $event_array['organizer']);
2990                                        $email2 = explode('&gt;', $email[1]);
2991                                $organizer = 'ORGANIZER;CN='.rtrim($email[0]).':mailto:'.$email2[0]."\r\n";
2992                                                        }
2993                                                                 
2994                            if(!$externo)
2995                            {
2996                                $tmpattach.=
2997                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
2998                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
2999                                ."LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3000                                                                .$organizer
3001                                ."UID:".$event_array['uid']."\r\n"
3002                                .$this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3003                                .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3004                                ."DESCRIPTION:".$description."\r\n"
3005                                ."SUMMARY:".$event_array['title']."\r\n"
3006                                ."LOCATION:".$event_array['location']."\r\n"
3007                                ."END:VEVENT\r\n";
3008                            }
3009                             else
3010                            {
3011                                $tmpattach.=
3012                                "DTSTART;TZID=".$timezone.":".$dtstart."\r\n"
3013                                ."DTEND;TZID=".$timezone.":".$dtend."\r\n"
3014                                ."DTSTAMP:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
3015                                .$organizer
3016                                .$this->mb_wordwrap("UID:".$event_array['uid']."\r\n",74,"\r\n ");
3017
3018                                switch ($metodo) {
3019                                    case 'PUBLISH':
3020                                          $tmpattach.=
3021                                             $this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
3022                                                                                        .$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
3023                                            .$this->mb_wordwrap("DESCRIPTION:".$description."\r\n",74,"\r\n ")
3024                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3025                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ");
3026                                        break;
3027                                    case 'REPLY':
3028                                            $tmpattach.=
3029                                             $this->mb_wordwrap("ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUESTS=0:mailto:".$importAccount['mail']."\r\n",74,"\r\n ")
3030                                            .'DESCRIPTION:\n'."\r\n"
3031                                            .$this->mb_wordwrap("LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n",74,"\r\n ") //Hora no formato UTC
3032                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ")
3033                                            ."SEQUENCE:0\r\n"
3034                                            ."STATUS:CONFIRMED\r\n"
3035                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
3036                                            ."TRANSP:OPAQUE\r\n";
3037                                        break;
3038                                    default:
3039                                           $tmpattach.=
3040                                             "DESCRIPTION:".$description."\r\n"
3041                                            ."SUMMARY:".$event_array['title']."\r\n"
3042                                            ."LOCATION:".$event_array['location']."\r\n";
3043                                        break;
3044                                }
3045                                  $tmpattach.= "END:VEVENT\r\n";
3046                            }
3047                           
3048                        }
3049                    $tmpattach.="END:VCALENDAR\r\n\r\n\r\n";   
3050                    return $tmpattach;
3051                }
3052
3053                function mb_wordwrap($str, $width=74, $break="\r\n")
3054                {
3055                    // Return short or empty strings untouched
3056                    if(empty($str) || mb_strlen($str, 'ISSO-8859-1') <= $width)
3057                        return $str;
3058
3059                    $br_width  = mb_strlen($break, 'ISSO-8859-1');
3060                    $str_width = mb_strlen($str, 'ISSO-8859-1');
3061                    $return = '';
3062                    $last_space = false;
3063
3064                    for($i=0, $count=0; $i < $str_width; $i++, $count++)
3065                    {
3066                        // If we're at a break
3067                        if (mb_substr($str, $i, $br_width, 'ISSO-8859-1') == $break)
3068                        {
3069                            $count = 0;
3070                            $return .= mb_substr($str, $i, $br_width, 'ISSO-8859-1');
3071                            $i += $br_width - 1;
3072                            continue;
3073                        }
3074
3075                        // Keep a track of the most recent possible break point
3076                        if(mb_substr($str, $i, 1, 'ISSO-8859-1') == " ")
3077                        {
3078                            $last_space = $i;
3079                        }
3080
3081                        // It's time to wrap
3082                        if ($count > $width)
3083                                {
3084                            // There are no spaces to break on!  Going to truncate :(
3085                            if(!$last_space)
3086                                    {
3087                                $return .= $break;
3088                                $count = 0;
3089                            }
3090                            else
3091                            {
3092                                // Work out how far back the last space was
3093                                $drop = $i - $last_space;
3094
3095                                // Cutting zero chars results in an empty string, so don't do that
3096                                if($drop > 0)
3097                                {
3098                                    $return = mb_substr($return, 0, -$drop);
3099                                }
3100
3101                                // Add a break
3102                                $return .= $break;
3103
3104                                // Update pointers
3105                                $i = $last_space + ($br_width - 1);
3106                                $last_space = false;
3107                                $count = 0;
3108                                    }
3109                                }
3110                               
3111                        // Add character from the input string to the output
3112                        $return .= mb_substr($str, $i, 1, 'ISSO-8859-1');
3113                    }
3114                    return $return;
3115                }
3116
3117                function getvCalendarParticipants($pExtParticipants,$pCalId)
3118                                {
3119                    $participants = explode(',', $pExtParticipants);
3120                    $return = '';
3121
3122                    foreach ($participants as $participant)
3123                                      {
3124                        $array = explode('"', $participant);
3125                        $mail = str_replace('<','', str_replace('>','',$array['2']));
3126                        if($mail && $array['1'])
3127                             $return .= 'ATTENDEE;CN='.$array['1'].';RSVP=TRUE:mailto:'.$mail."\r\n";
3128                    }
3129                    $db = $this->getDb();
3130                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3131                    $parts = array();
3132                    while($db->next_record())
3133                        array_push($parts, $db->row());
3134
3135                    $ldap = $this->getLdap();
3136                    foreach ($parts as $part)
3137                    {
3138                        $justthese = array('mail','cn');
3139                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3140                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3141                        $entry = ldap_get_entries($ldap, $search);
3142                        $return .= 'ATTENDEE;CN='.$entry[0]['cn'][0].';RSVP=TRUE:mailto:'.$entry[0]['mail'][0]."\r\n";
3143                                                        }
3144
3145                    return $return;
3146                                                        }
3147                               
3148                function getCalendarParticipantsArray($pCalId)
3149                {
3150                    $db = $this->getDb();
3151                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
3152                    $parts = array();
3153                    while($db->next_record())
3154                        array_push($parts, $db->row());
3155
3156                    $ldap = $this->getLdap();
3157                    foreach ($parts as $part)
3158                    {
3159                        $justthese = array('mail','cn');
3160                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
3161                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3162                        $entry = ldap_get_entries($ldap, $search);
3163                        $return [$entry[0]['mail'][0]] = array( 'CN'=> $entry[0]['cn'][0],'RSVP'=> 'TRUE' ,'ROLE' => 'REQ-PARTICIPANT');
3164                    }
3165                    return $return;
3166                }
3167
3168                function getvCalendarExternalParticipants($pCalId)
3169                {
3170
3171                    $db = $this->getDb();
3172                    $sql = "SELECT ex_participants FROM phpgw_cal WHERE cal_id = '$pCalId'";
3173                                $db->query($sql);
3174                               
3175                    $parts = array();
3176                    while($db->next_record())
3177                        array_push($parts, $db->row());
3178
3179                                        $participants = explode(',', $parts[0]['ex_participants']);
3180                    $return = '';
3181                                       
3182                                        $participants = unserialize(base64_decode($parts[0]['ex_participants']));
3183
3184                    foreach ($participants as $participant)
3185                    {   
3186                           $part = array();
3187
3188                           if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $participant['mail']))
3189                           {
3190                              $cn = null;
3191                              $mail = null;
3192                              preg_match ("(\"([^\"]*)\")", $participant['mail'], $cn);
3193                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3194
3195                              if($mail[1])
3196                              $part['mail'] =  $mail[1];
3197
3198                              if($cn[1])
3199                                $part['cn'] =  $cn[1];
3200
3201                                                         }
3202                                         else
3203                           if(preg_match("(<[^>]*@[^>]*>)", $participant['mail']))
3204                                                  {
3205                              $mail = null;
3206                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
3207                              if($mail[1])
3208                                $part['mail'] =  $mail[1];
3209
3210                                                   }
3211                           else
3212                           if(preg_match("([^ ]*@[^ ]*)", $participant['mail']))
3213                           {
3214                              $mail = null;
3215                              preg_match ('([^ ]*@[^ ]*)', $participant['mail'], $mail);
3216                              if($mail[0])
3217                                $part['mail'] =  $mail[0];
3218
3219                           }
3220
3221                          if(count($part) > 0)
3222                          {
3223                              if($part['cn'])
3224                                                                $return .= 'ATTENDEE;CN='.$part['cn'].';RSVP=TRUE:mailto:'.$part['mail']."\r\n";
3225                              else
3226                                                                $return .= 'ATTENDEE;RSVP=TRUE:mailto:'.$part['mail']."\r\n"; 
3227                             
3228                                      }
3229                                }
3230
3231                    return $return;
3232                        }
3233
3234
3235                function getDb()
3236                {
3237                    include_once('../phpgwapi/inc/class.db.inc.php');
3238                    // Conecta ao banco de dados
3239                    if (is_array($_SESSION['phpgw_info']['expresso']['server']))
3240                        $GLOBALS['phpgw_info']['server'] = $_SESSION['phpgw_info']['expresso']['server'];
3241                    else
3242                        $_SESSION['phpgw_info']['expresso']['server'] = $GLOBALS['phpgw_info']['server'];
3243
3244                    $db = new db();
3245                    $db->Halt_On_Error = 'no';
3246                    $db->connect(
3247                                $_SESSION['phpgw_info']['expresso']['server']['db_name'],
3248                                $_SESSION['phpgw_info']['expresso']['server']['db_host'],
3249                                $_SESSION['phpgw_info']['expresso']['server']['db_port'],
3250                                $_SESSION['phpgw_info']['expresso']['server']['db_user'],
3251                                $_SESSION['phpgw_info']['expresso']['server']['db_pass'],
3252                                $_SESSION['phpgw_info']['expresso']['server']['db_type']
3253                                );
3254                                // Fim Conecta Banco de dados
3255                    return $db;
3256                }
3257
3258                function getLdap()
3259                {
3260                    require_once(dirname(__FILE__).'/../../header.inc.php');
3261                    require_once(dirname(__FILE__).'/../../phpgwapi/inc/class.common.inc.php');
3262   
3263                    $common = new common();
3264                               
3265                    if ( (!empty($GLOBALS['phpgw_info']['server']['ldap_master_host'])) &&
3266                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_dn'])) &&
3267                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_pw'])) )
3268                        {
3269                            $ldap = $common->ldapConnect($GLOBALS['phpgw_info']['server']['ldap_master_host'],
3270                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_dn'],
3271                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_pw']);
3272                        }
3273                        else
3274                        {
3275                            $ldap = $common->ldapConnect();
3276                        }
3277                       
3278                    return $ldap;
3279                }
3280
3281                function getvCalendarOrganizer($pOrganizer)
3282                {
3283
3284                   
3285                       $organizer = array();
3286       
3287                       if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $pOrganizer))
3288                       {
3289                          $cn = null;
3290                          $mail = null;
3291                          preg_match ("(\"([^\"]*)\")", $pOrganizer, $cn);
3292                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3293
3294                          if($mail[1])
3295                          $organizer['mail'] =  $mail[1];
3296
3297                          if($cn[1])
3298                            $organizer['cn'] =  $cn[1];
3299
3300                       }
3301                       else
3302                       if(preg_match("(<[^>]*@[^>]*>)", $pOrganizer))
3303                       {
3304                          $mail = null;
3305                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
3306                          if($mail[1])
3307                            $organizer['mail'] =  $mail[1];
3308
3309                       }
3310                       else
3311                       if(preg_match("([^ ]*@[^ ]*)", $pOrganizer))
3312                       {
3313                          $mail = null;
3314                          preg_match ('([^ ]*@[^ ]*)', $pOrganizer, $mail);
3315                          if($mail[0])
3316                            $organizer['mail'] =  $mail[0];
3317
3318                       }
3319                       
3320                       if($organizer['cn']) $return = 'ORGANIZER;CN="'.$organizer['cn'].'":MAILTO:'.$organizer['mail']."\r\n";
3321                       else $return = 'ORGANIZER;MAILTO:'.$organizer['mail']."\r\n";
3322                       
3323                    return $return;
3324                }
3325
3326                /*!
3327                @function send_update
3328                @abstract sends update-messages to certain participants of an event
3329                @syntax send_update($msg_type,$to_notify,$old_event,$new_event=False)
3330                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
3331                @param $to_notify array with numerical user-ids as keys (!) (value is not used)
3332                @param $old_event Event before the change
3333                @param $new_event Event after the change
3334                */
3335                function send_update($msg_type,$to_notify,$old_event,$new_event = False, $user = False)
3336                        {
3337         
3338                        if (!is_array($to_notify)) $to_notify = array();
3339                        $owner = $old_event ? $old_event['owner'] : $new_event['owner'];
3340
3341                        if($owner === -2)
3342                            $to_notify[-2] = 'A';
3343
3344                        $version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
3345                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
3346                 
3347                        /*
3348                         * Caso o evento seja de uma conta compartilha busca obusca o cn e o email da conta
3349                         */
3350                        if($user)
3351                        {
3352                            $ldap = $this->getLdap(); 
3353                            $justthese = array("mail","cn");
3354                            $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3355                            $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3356                            $entry = ldap_get_entries($ldap, $search);
3357                            $sMail = $entry[0]['mail'][0];
3358                            $sCN = $entry[0]['cn'][0];
3359                            $sUN = $user;
3360                        }
3361                        else
3362                        {
3363                            $sMail = $GLOBALS['phpgw_info']['user']['email'];
3364                            $sCN = $GLOBALS['phpgw_info']['user']['fullname'];
3365                            $sUN = $GLOBALS['phpgw_info']['user']['account_id'];
3366                        }
3367                        //------------------------------------------------------------------------------------//
3368                 
3369                    $temp_tz_offset = $this->prefs['common']['tz_offset'];
3370                        $temp_timeformat = $this->prefs['common']['timeformat'];
3371                        $temp_dateformat = $this->prefs['common']['dateformat'];
3372                        $tz_offset = ((60 * 60) * (int)$temp_tz_offset);
3373
3374                        if($old_event != False)
3375                        {
3376                                $t_old_start_time = $this->maketime($old_event['start']);
3377                                if($t_old_start_time < (time() - 86400))
3378                                        return False;
3379                                }
3380
3381                        $temp_user = $GLOBALS['phpgw_info']['user'];
3382                        if (!$user) $user = $this->owner;
3383                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
3384                        $this->prefs = $GLOBALS['phpgw_info']['user']['preferences'];
3385
3386                        $event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
3387                        if($old_event != False)
3388                        {
3389                                $old_starttime = $t_old_start_time - $GLOBALS['phpgw']->datetime->tz_offset;
3390                        }
3391                        $starttime = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
3392                        $endtime   = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
3393
3394                        switch($msg_type)
3395                        {
3396                                case MSG_DELETED:
3397                                        $action = lang('Canceled');
3398                                        $msg = 'Canceled';
3399                                        $msgtype = '"calendar";';
3400                                        $method = 'cancel';
3401                                        $typesend = 1;
3402                                        break;
3403                                case MSG_MODIFIED:
3404                                        $action = lang('Modified');
3405                                        $msg = 'Modified';
3406                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3407                                        $method = 'request';
3408                                        $typesend = 2;
3409                                        break;
3410                                case MSG_ADDED:
3411                                        $action = lang('Added');
3412                                        $msg = 'Added';
3413                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
3414                                        $method = 'request';
3415                                        $typesend = 3;
3416                                        break;
3417                                case MSG_REJECTED:
3418                                        $action = lang('Rejected');
3419                                        $msg = 'Response';
3420                                        $msgtype = '"calendar";';
3421                                        $method = 'reply';
3422                                        $typesend = 4;
3423                                        break;
3424                                case MSG_TENTATIVE:
3425                                        $action = lang('Tentative');
3426                                        $msg = 'Response';
3427                                        $msgtype = '"calendar";';
3428                                        $method = 'reply';
3429                                        $typesend = 5;
3430                                        break;
3431                                case MSG_ACCEPTED:
3432                                        $action = lang('Accepted');
3433                                        $msg = 'Response';
3434                                        $msgtype = '"calendar";';
3435                                        $method = 'reply';
3436                                        $typesend = 6;
3437                                        break;
3438                                case MSG_ALARM:
3439                                        $action = lang('Alarm');
3440                                        $msg = 'Alarm';
3441                                        $msgtype = '"calendar";';
3442                                        $method = 'publish';    // duno if thats right
3443                                        $typesend = 7;
3444                                        break;
3445                                default:
3446                                        $method = 'publish';
3447                                        $typesend = 8;
3448                        }
3449                        $notify_msg = $this->prefs['calendar']['notify'.$msg];
3450                        if (empty($notify_msg))
3451                                $notify_msg = $this->prefs['calendar']['notifyAdded'];  // use a default
3452                       
3453                        $details = array(                       // event-details for the notify-msg
3454                                'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
3455                                'action'      => $action,
3456                        );
3457                        $event_arr = $this->event2array($event);
3458                        foreach($event_arr as $key => $val)
3459                        {
3460                                $details[$key] = $val['data'];
3461                        }
3462                       
3463                        $details['participants'] = implode("\n",$details['participants']);
3464
3465                        $details['link'] = $GLOBALS['phpgw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uicalendar.view&cal_id='.$event['id'];
3466                        // if url is only a path, try guessing the rest ;-)
3467                        if ($GLOBALS['phpgw_info']['server']['webserver_url'][0] == '/')
3468                        {
3469                                $details['link'] = ($GLOBALS['phpgw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
3470                                        ($GLOBALS['phpgw_info']['server']['hostname'] ? $GLOBALS['phpgw_info']['server']['hostname'] : 'localhost').
3471                                        $details['link'];
3472                        }
3473                       
3474                        //Seta o email usando phpmailer
3475                        define('PHPGW_INCLUDE_ROOT','../');     
3476                        define('PHPGW_API_INC','../phpgwapi/inc');     
3477                        include_once(PHPGW_API_INC.'/class.phpmailer.inc.php');
3478                        $mail = new PHPMailer();
3479                        $mail->IsSMTP();
3480                        $boemailadmin = CreateObject('emailadmin.bo');
3481                        $emailadmin_profile = $boemailadmin->getProfileList();
3482                        $emailadmin = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
3483               
3484                        $mail->Host = $emailadmin['smtpServer'];
3485                        $mail->Port = $emailadmin['smtpPort'];
3486                        $mail->From = $sMail;
3487                        $mail->FromName = $sCN;
3488                        $mail->IsHTML(true);
3489                        //Inicializa vari?vel de retorno.
3490                        $returncode=true;               
3491                        // Aqui e enviado o email
3492                        foreach($to_notify as $userid => $statusid)
3493                        {
3494                                $mail->ClearAttachments();
3495                               
3496                                $userid = (int)$userid;
3497
3498                                if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g' || ($sUN == $userid &&  $msg_type != MSG_ALARM))
3499                                    continue;   // dont notify rejected participants or to == send
3500                               
3501                                if($userid != $sUN  ||  $msg_type == MSG_ALARM)
3502                                {
3503                                        print_debug('Msg Type',$msg_type);
3504                                       
3505                                        print_debug('UserID',$userid);
3506
3507                                        $preferences = CreateObject('phpgwapi.preferences',$userid);
3508                                        $part_prefs = $preferences->read_repository();
3509
3510                                        if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event))
3511                                        {
3512                                                continue;
3513                                        }
3514                                        $GLOBALS['phpgw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
3515                                        $details['to-fullname'] = $GLOBALS['phpgw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
3516
3517                                        $to = $preferences->email_address($userid);
3518                                       
3519                                       
3520                                        if( $userid === -2 )
3521                                        {
3522                                                $to = htmlspecialchars_decode( $event['organizer'] );
3523                                        }
3524                                       
3525                                        if (empty($to) || $to[0] == '@' || $to[0] == '$')       // we have no valid email-address
3526                                        {
3527                                                //echo "<p>bocalendar::send_update: Empty email adress for user '".$details['to-fullname']."' ==> ignored !!!</p>\n";
3528                                                continue;
3529                                        }
3530                                        print_debug('Email being sent to',$to);
3531
3532                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
3533                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
3534                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
3535
3536                                        $GLOBALS['phpgw']->datetime->tz_offset = ((60 * 60) * (int)$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']);
3537
3538                                        if($old_starttime)
3539                                        {
3540                                                $details['olddate'] = $GLOBALS['phpgw']->common->show_date($old_starttime);
3541                                        }
3542                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3543                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3544                                       
3545                                       
3546                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3547                                       
3548                                        switch($part_prefs['calendar']['update_format'])
3549                                        {
3550                                                case  'extended':
3551                                                        //$body .= "\n\n".lang('Event Details follow').":\n";
3552                                                        $body = '';
3553                                                        $body .= "<br>".lang('Event Details follow')." :: ";
3554                                                        foreach($event_arr as $key => $val)
3555                                                        {
3556                                                                // titulo
3557                                                                if($key =='title')
3558                                                                {
3559                                                                        $var1 = $val['field'];
3560                                                                        $vardata1 = $details[$key];
3561                                                                }
3562                                                                //descricao
3563                                                                if($key =='description')
3564                                                                {
3565                                                                        $var2 = $val['field'];
3566                                                                        $vardata2 = $details[$key];
3567                                                                }
3568                                                                //dt inicio
3569                                                                if($key =='startdate')
3570                                                                {
3571                                                                        switch(trim($part_prefs['common']['dateformat']))
3572                                                                        {
3573                                                                               
3574                                                                                case ($part_prefs['common']['dateformat'] === "m/d/Y" || $part_prefs['common']['dateformat'] === "m-d-Y" || $part_prefs['common']['dateformat'] === "m.d.Y"):
3575                                                                                        $var3 = $val['field'];
3576                                                                                        $vardata3 = $details[$key];
3577                                                                                        $newmounth3 = substr($vardata3,0,2);
3578                                                                                        $newday3 = substr($vardata3,3,2);
3579                                                                                        $newyear3 = substr($vardata3,6,4);
3580                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3581                                                                                        break;
3582                                                                                       
3583                                                                                case    ($part_prefs['common']['dateformat'] === "Y/d/m" || $part_prefs['common']['dateformat'] === "Y-d-m" || $part_prefs['common']['dateformat'] === "Y.d.m"):
3584
3585                                                                                        $var3 = $val['field'];
3586                                                                                        $vardata3 = $details[$key];
3587                                                                                        $newyear3 = substr($vardata3,0,4);
3588                                                                                        $newday3 = substr($vardata3,5,2);
3589                                                                                        $newmounth3 = substr($vardata3,8,2);
3590                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3591                                                                                        break;
3592
3593                                                                                case ($part_prefs['common']['dateformat'] === "Y/m/d" || $part_prefs['common']['dateformat'] === "Y-m-d" || $part_prefs['common']['dateformat'] === "Y.m.d"):
3594
3595                                                                                        $var3 = $val['field'];
3596                                                                                        $vardata3 = $details[$key];
3597                                                                                        $newyear3 = substr($vardata3,0,4);
3598                                                                                        $newmounth3 = substr($vardata3,5,2);
3599                                                                                        $newday3 = substr($vardata3,8,2);
3600                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3601                                                                                        break;
3602
3603                                                                                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"):
3604                                                                               
3605                                                                                        $var3 = $val['field'];
3606                                                                                        $vardata3 = $details[$key];
3607                                                                                        $newday3 = substr($vardata3,0,2);
3608                                                                                        $newmounth3 = substr($vardata3,3,2);
3609                                                                                        $newyear3 = substr($vardata3,6,4);
3610                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
3611                                                                                        break;
3612                                                                       
3613                                                                        }
3614                                                                       
3615                                                                }
3616                                                                //dt final
3617                                                                if($key =='enddate')
3618                                                                {
3619                                                                        $var4 = $val['field'];
3620                                                                        $vardata4 = $details[$key];
3621                                                                }
3622                                                                //localizacao
3623                                                                if($key =='location')
3624                                                                {
3625                                                                        $var8 = $val['field'];
3626                                                                        $vardata8 = $details[$key];
3627                                                                }
3628                                                                //participantes
3629                                                                if($key =='participants')
3630                                                                {
3631                                                                        $var5 = $val['field'];
3632                                                                        foreach($val['data'] as $NewKey => $NewVal)
3633                                                                        {
3634                                                                                //Research inside of ldap ( Pesquisa dentro do ldap )
3635                                                                                $newvalue = $this->so->search_uidNumber($to);
3636                                                                                foreach($newvalue as $tmp)
3637                                                                                {
3638                                                                                        $tmpmail = $tmp['mail'][0];
3639                                                                                        $tmpuid = $tmp['uidnumber'][0];
3640                                                                                        if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
3641                                                                                        {
3642                                                                                                        if($typesend == 3)
3643                                                                                                        {
3644
3645                                                                                                                $lang1 = lang("To See Commitment");
3646                                                                                                                $varbuttom = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id=$event[id]&date=$newall3' method='POST'>
3647                                                                                                                                                                  <input type='submit' value='$lang1'>
3648                                                                                                                                                                   </form>";
3649                                                                                                                $lang2 = lang("To accept");
3650                                                                                                                $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\")'>";
3651                                                                                                               
3652                                                                                                                $lang6 = lang("Tentative");
3653                                                                                                                $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\")'>";
3654                                                                                                               
3655
3656                                                                                                                $lang3 = lang("To reject");
3657                                                                                                                $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\")'>";
3658                                                                                                               
3659                                                                                                                $lang4 = lang("Alarm");
3660                                                                                                                $varbuttom3 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uialarm.manager method='POST'>
3661                                                                                                                                                                  <input type='submit' value='$lang4'>
3662                                                                                                                                                                  <input type='hidden' name='cal_id' value=$event[id]>
3663                                                                                                                                                                   </form>";
3664                                                                                                                                                                   
3665                                                                                                                $lang5 = lang("Suggest new hour");
3666                                                                                                                $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'>
3667                                                                                                                                                                  <input type='submit' value='$lang5'>
3668                                                                                                                                                                   </form>";
3669                                                                                                        }
3670                                                                                                        else
3671                                                                                                        {
3672                                                                                                                        $varbuttom  = "";
3673                                                                                                                        $varbuttom1 = "";
3674                                                                                                                        $varbuttom2 = "";
3675                                                                                                                        $varbuttom3 = "";
3676                                                                                                                        $varbuttom4 = "";
3677                                                                                                                        $varbuttom5 = "";
3678                                                                                                        }
3679                                                                                        }
3680                                                                                        // It only mounts variavel with the name of the participants of the list ( Monta a variavel somente com o nome dos participantes da lista)
3681                                                                                        if($typesend == 3)
3682                                                                                        {
3683                                                                                                list($tmpvardata5,$tmp2vardata5) = explode("(",$NewVal);
3684                                                                                                $vardata5 = $tmpvardata5."<br>";
3685                                                                                        }
3686                                                                                        else
3687                                                                                        {
3688                                                                                                $vardata5 = $NewVal."<br>";
3689                                                                                        }
3690                                                                               
3691                                                                                }
3692                                                                                $vardata6 .= $vardata5;
3693                                                                                unset($vardata5);
3694                                                                        }
3695                                                                }               
3696                                                        }
3697                                                        //To mount the message as text/html (Para montar a mensagem como text/html - /phpgwapi/inc/class.send.inc.php )
3698                                                        $content_type = "text/html";
3699                                                        //It mounts the body of the message (Monta o corpo da mensagem)
3700                                                       
3701                                                        // A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
3702                                                        if(!PHPGW_APP_TPL)
3703                                                         define ("PHPGW_APP_TPL",PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3704                                                       
3705                                                                $body = CreateObject('phpgwapi.Template',PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
3706                                                        $body->set_file(Array('calendar' => 'body_email.tpl'));
3707                                                        $body->set_block('calendar','list');
3708                                                        $var = Array(
3709                                                                'script'                        => $script,
3710                                                                'subject'                       => $body1,
3711                                                                'var1'                          => $var1,
3712                                                                'vardata1'                      => $vardata1,
3713                                                                'var2'                          => $var2,
3714                                                                'vardata2'                      => $vardata2,
3715                                                                'var3'                          => $var3,
3716                                                                'vardata3'                      => $vardata3,
3717                                                                'var4'                          => $var4,
3718                                                                'vardata4'                      => $vardata4,
3719                                                                'var5'                          => $var5,
3720                                                                'vardata6'                      => $vardata6,
3721                                                                'var8'                          => $var8,
3722                                                                'vardata8'                      => $vardata8,
3723                                                                'varbuttom'                     => $varbuttom,
3724                                                                'varbuttom1'            => $varbuttom1,
3725                                                                'varbuttom2'            => $varbuttom2,
3726                                                                'varbuttom3'            => $varbuttom3,
3727                                                                'varbuttom4'            => $varbuttom4,
3728                                                                'varbuttom5'            => $varbuttom5
3729                                                        );
3730                                                        $body->set_var($var);
3731                                                        $tmpbody = $body->fp('out','list');
3732                                                                                                               
3733                                                        break;
3734
3735                                                case 'ical':
3736                                                        $content_type = "calendar; method=$method; name=calendar.ics";
3737/*                                                      if ($body != '')
3738                                                        {
3739                                                                $boundary = '----Message-Boundary';
3740                                                                $body .= "\n\n\n$boundary\nContent-type: text/$content_type\n".
3741                                                                        "Content-Disposition: inline\nContent-transfer-encoding: 7BIT\n\n";
3742                                                                $content_type = '';
3743                                                        }
3744*/
3745                                                        $body = ExecMethod('calendar.boicalendar.export',array(
3746                                                                'l_event_id'  => $event['id'],
3747                                                                'method'      => $method,
3748                                                                'chunk_split' => False
3749                                                        ));
3750                                                        break;
3751                                        }
3752                                       
3753                                        $mail->AddAddress($to);
3754                                        $mail->Body = $tmpbody;     
3755                                        $mail->From = $sMail;
3756                                        $mail->FromName = $sCN;
3757                                        $mail->Sender = $mail->From;
3758                                        $mail->SenderName = $mail->FromName;
3759                                        $mail->Subject = $subject;
3760                                        unset($vardata5);
3761                                        unset($vardata6);
3762                                       
3763                                        // Envia aviso ao participante.
3764                                        if(!$mail->Send()) {                           
3765                                                $returncode = false;
3766                                                $errorInfo['participants'] = $mail->ErrorInfo;
3767                        }
3768
3769                                        $mail->ClearAddresses();   
3770
3771                                }
3772                            }
3773
3774                        if(!is_object($this->ex_participants))
3775                        {
3776                            include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
3777                            $objexP = new exParticipants();
3778                            $objexP->setParticipantsBySerializable($this->ex_participants);
3779                                }
3780                                else
3781                            $objexP = $this->ex_participants;
3782
3783                       
3784                        if($msg_type === MSG_ADDED && count($this->extAdded) > 0)
3785                               $extMails = $this->extAdded; 
3786                        else if($msg_type === MSG_DELETED && count($this->extDeleted) > 0)
3787                                $extMails = $this->extDeleted; 
3788                        else
3789                            $extMails = array_diff($objexP->getParticipantsMailsArray(), $this->alreadyExtNotifieds);
3790                               
3791                        if(count($extMails) > 0){
3792                                $mail->ClearAllRecipients();
3793                             
3794                                $to = array();
3795                                if(!$subject) {
3796                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
3797                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
3798                                        list($subject,$body1) = preg_split('/\n/',$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
3799                                }
3800                               
3801                                foreach($extMails as $index => $ex_participant){
3802                                        $ex_participant = trim($ex_participant);
3803                                        $ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
3804                                                if($ex_participant)
3805                                                        $to[] = $ex_participant;
3806                                }               
3807                               
3808                                foreach($to as $i => $to_array)
3809                                        $mail->AddAddress($to_array);
3810                               
3811                                $_body = explode("<hr size='1' width='100%'>",$tmpbody);
3812                                $tmpbody = $_body[0] ? $_body[0] : $subject ;
3813                                $tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($objexP->getParticipantsMailsString());
3814                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[description]."<br>";
3815                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
3816                                $tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
3817                                .lang("This message was sent by server. You must send a message to sender to confirm this event")."<br>"
3818                                .lang("This is an external event. Even if it added to your expresso its can be changed any time at all")."</font><br>";
3819                               
3820                                if ($GLOBALS['bocalendar']->so->cal->event[start][month] > 10)
3821                                        $event_month=$GLOBALS['bocalendar']->so->cal->event[start][month];
3822                                else
3823                                        $event_month="0".$GLOBALS['bocalendar']->so->cal->event[start][month];
3824                                //attach extern vcalendar/icalendar (ics)                       
3825                                // define('context','$GLOBALS.bocalendar.so.cal.event');
3826                               
3827                                $evt = $GLOBALS['bocalendar']->so->cal->event;
3828                                                                 
3829                                /*
3830                                 * Cria Arqvuio ICS
3831                                 */
3832                                require_once dirname(__FILE__).'/../../services/class.servicelocator.php';
3833                                $icalService = ServiceLocator::getService('ical');
3834
3835                                if($msg_type == MSG_DELETED)
3836                                {
3837                                        $icalService->createICal(strtoupper($method));
3838                                        $icalService->addEvent(
3839                                            $old_event['start']['year'].'-'.$old_event['start']['month'].'-'.$old_event['start']['mday'].' '.$old_event['start']['hour'].':'.$old_event['start']['min'].':00',
3840                                            $old_event['end']['year'].'-'.$old_event['end']['month'].'-'.$old_event['end']['mday'].' '.$old_event['end']['hour'].':'.$old_event['end']['min'].':00',
3841                                            array($sMail => array('CN'=> $sCN)),
3842                                            $old_event['title'],
3843                                            $old_event['description'],
3844                                            $old_event['location'],
3845                                            false,
3846                                            false,
3847                                            false,
3848                                            $old_event['uid']
3849                                            );
3850                                }
3851                                else
3852                                {
3853                                        $attendee = array();
3854                                        foreach($to as $value)
3855                                            $attendee[$value] = array('RSVP' => 'TRUE','ROLE' => 'REQ-PARTICIPANT');
3856
3857                                        $attendee =  array_merge($attendee,$this->getCalendarParticipantsArray($evt['id']));
3858                                        $icalService->createICal(strtoupper($method));
3859                                        $icalService->addEvent(
3860                                            $evt['start']['year'].'-'.$evt['start']['month'].'-'.$evt['start']['mday'].' '.$evt['start']['hour'].':'.$evt['start']['min'].':00',
3861                                            $evt['end']['year'].'-'.$evt['end']['month'].'-'.$evt['end']['mday'].' '.$evt['end']['hour'].':'.$evt['end']['min'].':00',
3862                                            array($sMail => array('CN'=> $sCN)),
3863                                            $evt['title'],
3864                                            $evt['description'],
3865                                            $evt['location'],
3866                                            $attendee,
3867                                            false,
3868                                            false,
3869                                            $evt['uid']
3870                                            );
3871
3872                                }
3873
3874
3875                                $tmpattach = $icalService->getICal();
3876                                //-------------------------------------------------//
3877                               
3878                                if($tmpattach){                                 
3879                                        $tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
3880                                        srand((double)microtime()*1000000);
3881                                        $random_number = rand(100000000,999999999);
3882                                        $newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
3883                                        $filename = $tempdir . $newfilename;
3884                                        $attach_fd = fopen($filename,"w+");
3885                                        fwrite($attach_fd,$tmpattach);
3886                                        $mail->AddAttachment($filename, "extern.ics", "base64", "text/plain"); // "application/octet-stream"
3887                                        fclose($attach_fd);
3888                                }
3889                                $mail->From = $sMail;
3890                                $mail->FromName = $sCN;
3891                                $mail->Sender = $mail->From;
3892                                $mail->SenderName = $mail->FromName;
3893                                $mail->Subject = lang("External event from Expresso");
3894                                $mail->Body = $tmpbody;
3895                                                                                                                                               
3896                                if(!$mail->Send())
3897                                {
3898                                        $returncode=false;
3899                                        $errorInfo['ex_participants'] = $mail->ErrorInfo;
3900                                }
3901                                else
3902                                {
3903                                        $returncode=true;
3904                                }
3905                        }
3906
3907
3908                        if((is_int($this->user) && $this->user != $temp_user['account_id']) ||
3909                                (is_string($this->user) && $this->user != $temp_user['account_lid']))
3910                        {
3911                                $GLOBALS['phpgw_info']['user'] = $temp_user;
3912                        }       
3913
3914                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $temp_tz_offset;
3915                        $GLBOALS['phpgw']->datetime->tz_offset = ((60 * 60) * $temp_tz_offset);
3916                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $temp_timeformat;
3917                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
3918                       
3919                        // Notifica por email o criador do compromisso, com as poss?veis falhas.                                               
3920                        if($errorInfo) {
3921                                $tmpbody = "<font color='red'>".lang("The following commitment had problems for DELIVERING the NOTIFICATION messages.").".</font><br>";
3922                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
3923                                $tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";                         
3924                                $tmpbody.= "<br><u>".lang("Failed to delivery")."</u><br>";
3925                                $failed = false;                               
3926                                if(strstr($errorInfo['participants'],"recipients_failed")){
3927                                        $failed = explode("recipients_failed",$errorInfo['participants']);
3928                                        $tmpbody.= lang("to").": ".$failed[1];
3929                                }
3930                                if(strstr($errorInfo['ex_participants'],"recipients_failed")){
3931                                        $failed = explode("recipients_failed",$errorInfo['ex_participants']);
3932                                        $tmpbody.= lang("to").": ".$failed[1];
3933                                }                       
3934                                if(!$failed) {
3935                                        $tmpbody.= lang("Description").":<br>";
3936                                        $tmpbody.= $errorInfo['participants'];
3937                                        $tmpbody.= "<br>".$errorInfo['ex_participants'];
3938                                }
3939                                $tmpbody.= "<br>".lang("Subject").": ".$subject;
3940                                // Reinicializa o objeto, devido ao erro anterior na entrega.
3941                               
3942                                $mail = new PHPMailer();
3943                                $mail->IsSMTP();
3944                                $mail->Host = $emailadmin['smtpServer'];
3945                                $mail->Port = $emailadmin['smtpPort'];
3946                                $mail->From = $sMail;
3947                                $mail->FromName = $sCN;
3948                                $mail->Sender = $mail->From;
3949                                $mail->SenderName = $mail->FromName;
3950                                $mail->IsHTML(True);
3951                                $mail->Subject = lang("calendar event")." - ".lang("email notification");                                                       
3952                                $mail->Body = $tmpbody;                                 
3953                                $mail->AddAddress($sMail);
3954                                if(!$mail->Send())                     
3955                                        $returncode = false;
3956                                else
3957                                        $returncode =  true;
3958                        }
3959                        return $returncode;
3960                }
3961               
3962               
3963               
3964                /**
3965                 * @license http://www.gnu.org/copyleft/gpl.html GPL
3966                 * @author Prognus Software Livre (http://www.prognus.com.br)
3967                 */
3968                function send_suggestion_external_owner($cal_id, $uid, $to, $time_suggest, $array_data_inicio, $array_data_final, $title, $description, $location, $ex_participants,$user = false)
3969                {
3970
3971                    if($cal_id)
3972                        $event =  $this->so->read_entry($cal_id);
3973                    else
3974                    {
3975                        $event = $this->restore_from_appsession();
3976                        $this->so->add_entry( $event , false);
3977                    }
3978                   
3979                    $this->so->cal->set_status($event['id'],$user,2);
3980
3981
3982                    if($user && $user != $GLOBALS['phpgw_info']['user']['account_id'])
3983                    {
3984                        $ldap = $this->getLdap();
3985                        $justthese = array("mail","cn");
3986                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
3987                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
3988                        $entry = ldap_get_entries($ldap, $search);
3989                        $ownerMail = $entry[0]['mail'][0];
3990                        $ownerCN = $entry[0]['cn'][0];
3991                     }
3992                     else
3993                     {
3994                        $ownerMail = $GLOBALS['phpgw_info']['user']['email'];
3995                        $ownerCN = $GLOBALS['phpgw_info']['user']['fullname'];
3996                     }
3997                     
3998                    require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
3999                    $icalService = ServiceLocator::getService('ical');
4000                    $dia_inicio = $array_data_inicio[0];
4001                    $mes_inicio = $array_data_inicio[1];
4002                    $ano_inicio = $array_data_inicio[2];
4003                    $hora_inicio = $time_suggest['hora_inicio'];
4004                    $minuto_inicio = $time_suggest['minuto_inicio'];
4005                    $dia_final = $array_data_final[0];
4006                    $mes_final = $array_data_final[1];
4007                    $ano_final = $array_data_final[2];
4008                    $hora_final = $time_suggest['hora_final'];
4009                    $minuto_final = $time_suggest['minuto_final'];
4010
4011                    $dtStart = $array_data_inicio[2] . '/' .
4012                               $array_data_inicio[1] . '/' .
4013                               $array_data_inicio[0] . ' ' .
4014                               $time_suggest['hora_inicio'] . ':' .
4015                               $time_suggest['minuto_inicio'] . ':00';
4016
4017                    $dtEnd = $array_data_final[2] . '/' .
4018                             $array_data_final[1] . '/' .
4019                             $array_data_final[0] . ' ' .
4020                             $time_suggest['hora_final'] . ':' .
4021                             $time_suggest['minuto_final'] . ':00';
4022
4023                    $icalService->createICal('REPLY');
4024
4025                    $other = array( 'X-MICROSOFT-CDO-IMPORTANCE' => '1',
4026                                    'X-EXPRESSO-SUGGESTION-HOUR' => '1',
4027                                    'CLASS' => 'PUBLIC',
4028                                    'PRIORITY' => '5',
4029                                    'SEQIENCE' => '0',
4030                                    'TRANSP' => 'OPAQUE');
4031
4032                    /* Corpo do email */
4033                    $tmpbody2 = lang("The sender suggested a new hours for the appointment");
4034                    $tmpbody2.= " <br /> <b>" . lang("Title") . ":</b> $title";
4035                    $tmpbody2.= " <br /> <b>" . lang("Details") . ":</b> <br /> <br /> <b>" . lang("Start") . "  </b>" . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4036                    $tmpbody2.= " <br /> <b>" . lang("End") . " </b>" . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "<br><br><br><br>";
4037                    $tmpbody = lang("The sender suggested a new hours for the appointment");
4038                    $tmpbody.= " \r\n " . lang("Title") . ": $title";
4039                    $tmpbody.= " \r\n " . lang("Suggestion") . ": \r\n \r\n " . lang("Start") . "  " . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
4040                    $tmpbody.= " \r\n " . lang("End") . " " . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "";
4041
4042                    $icalService->addEvent($dtStart,
4043                            $dtEnd,
4044                            $to,
4045                            $title,
4046                            utf8_encode($tmpbody),
4047                            $location,
4048                            array($ownerMail => array('CN' => $ownerCN, 'PARTSTAT' => 'TENTATIVE')),
4049                            $other,
4050                            false,
4051                            $uid
4052                    );
4053                   
4054                    $tmpattach =  $icalService->getICal();                   
4055                   
4056                    $mailService = ServiceLocator::getService('mail');
4057                    $mailService->addStringAttachment($tmpattach, 'suggestion.ics', 'application/ics');
4058                    $mailService->addStringAttachment($tmpattach, 'vcalendar.ics', 'text/calendar; charset=utf-8; method=REPLY;', '7bit', 'inline');
4059                    $mailService->sendMail($to, $ownerMail, $title, $tmpbody2);
4060                     
4061                    return $event['id'];                   
4062                }               
4063               
4064                function send_alarm($alarm)
4065                {
4066                        //echo "<p>bocalendar::send_alarm("; print_r($alarm); echo ")</p>\n";
4067                       
4068                        $GLOBALS['phpgw_info']['user']['account_id'] = $this->owner = $alarm['owner'];
4069
4070                        if (!$alarm['enabled'] || !$alarm['owner'] || !$alarm['cal_id'] || !($event = $this->so->read_entry($alarm['cal_id'])))
4071                        {
4072                                return False;   // event not found
4073                        }
4074                        if ($alarm['all'])
4075                        {
4076                                $to_notify = $event['participants'];
4077                        }
4078                        elseif ($this->check_perms(PHPGW_ACL_READ,$event))      // checks agains $this->owner set to $alarm[owner]
4079                        {
4080                                $to_notify[$alarm['owner']] = 'A';
4081                        }
4082                        else
4083                        {
4084                                return False;   // no rights
4085                        }
4086                        return $this->send_update(MSG_ALARM,$to_notify,$event,False,$alarm['owner']);
4087                }
4088
4089                function get_alarms($event_id)
4090                {
4091                        return $this->so->get_alarm($event_id);
4092                }
4093
4094                function alarm_today($event,$today,$starttime)
4095                {
4096                        $found = False;
4097                        @reset($event['alarm']);
4098                        $starttime_hi = $GLOBALS['phpgw']->common->show_date($starttime,'Hi');
4099                        $t_appt['month'] =$GLOBALS['phpgw']->common->show_date($today,'m');
4100                        $t_appt['mday'] = $GLOBALS['phpgw']->common->show_date($today,'d');
4101                        $t_appt['year'] = $GLOBALS['phpgw']->common->show_date($today,'Y');
4102                        $t_appt['hour'] = $GLOBALS['phpgw']->common->show_date($starttime,'H');
4103                        $t_appt['min']  = $GLOBALS['phpgw']->common->show_date($starttime,'i');
4104                        $t_appt['sec']  = 0;
4105                        $t_time = $this->maketime($t_appt) - $GLOBALS['phpgw']->datetime->tz_offset;
4106                        $y_time = $t_time - 86400;
4107                        $tt_time = $t_time + 86399;
4108                        print_debug('T_TIME',$t_time.' : '.$GLOBALS['phpgw']->common->show_date($t_time));
4109                        print_debug('Y_TIME',$y_time.' : '.$GLOBALS['phpgw']->common->show_date($y_time));
4110                        print_debug('TT_TIME',$tt_time.' : '.$GLOBALS['phpgw']->common->show_date($tt_time));
4111                        while(list($key,$alarm) = each($event['alarm']))
4112                        {
4113                                if($alarm['enabled'])
4114                                {
4115                                        print_debug('TIME',$alarm['time'].' : '.$GLOBALS['phpgw']->common->show_date($alarm['time']).' ('.$event['id'].')');
4116                                        if($event['recur_type'] != MCAL_RECUR_NONE)   /* Recurring Event */
4117                                        {
4118                                                print_debug('Recurring Event');
4119                                                if($alarm['time'] > $y_time && $GLOBALS['phpgw']->common->show_date($alarm['time'],'Hi') < $starttime_hi && $alarm['time'] < $t_time)
4120                                                {
4121                                                        $found = True;
4122                                                }
4123                                        }
4124                                        elseif($alarm['time'] > $y_time && $alarm['time'] < $t_time)
4125                                        {
4126                                                $found = True;
4127                                        }
4128                                }
4129                        }
4130                        print_debug('Found',$found);
4131                        return $found;
4132                }
4133
4134                function prepare_recipients(&$new_event,$old_event,$userSend)
4135                {
4136                        //Verifica se ouve alguem deletado
4137                        foreach($old_event['participants'] as $key => $value)
4138                           if(!array_key_exists($key, $new_event['participants']))
4139                                {
4140                               $this->deleted[$key] = $value;
4141                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4142                                }
4143                        //Verifica se ouve alguem adicionado
4144                        foreach($new_event['participants'] as $key => $value)
4145                           if(!array_key_exists($key, $old_event['participants']))
4146                                {
4147                               $this->added[$key] = $value;
4148                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4149                        }
4150                       
4151                        //Verifica se ouve alguem modificado
4152                        foreach($new_event['participants'] as $key => $value)
4153                        {
4154                            if(array_key_exists($key, $old_event['participants']))                       
4155                                {
4156                                if($old_event['participants'][$key] != $value)
4157                                {
4158                                    $this->modified[$key] = $value; 
4159                                    $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
4160                                }
4161                                }
4162                        }
4163                         //Verificando alterações em usuarios externos
4164                         include_once(dirname(__FILE__).'/class.ex_participants.inc.php');
4165                         $extOld = new exParticipants();
4166                         $extNew = new exParticipants();
4167                         
4168                         $extOld->setParticipantsBySerializable($old_event['ex_participants']);
4169                         $extNew->setParticipantsBySerializable($new_event['ex_participants']);
4170                       
4171                         $oldArray = $extOld->getParticipantsMailsArray();
4172                         $newArray = $extNew->getParticipantsMailsArray();
4173                         
4174                        //Verifica se ouve alguem deletado
4175                        $this->extDeleted = array_diff($oldArray, $newArray);
4176                       
4177                        //Verifica se ouve alguem adicionado
4178                        $this->extAdded = array_diff($newArray, $oldArray);
4179                       
4180                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extDeleted);
4181                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extAdded);
4182                        //---------------------------------------------------------------------------------//
4183                       
4184                        if(count($this->added) > 0 || count($this->extAdded))
4185                                $this->send_update(MSG_ADDED,$this->added,'',$new_event,$userSend);
4186                       
4187                        if(count($this->modified) > 0)
4188                                $this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event,$userSend);
4189                       
4190                        if(count($this->deleted) > 0 || count($this->extDeleted))
4191                                $this->send_update(MSG_DELETED,$this->deleted,$old_event,false,$userSend);
4192                                               
4193                }
4194
4195                function remove_doubles_in_cache($firstday,$lastday)
4196                {
4197                        $already_moved = Array();
4198                        for($v=$firstday;$v<=$lastday;$v++)
4199                        {
4200                                if (!$this->cached_events[$v])
4201                                {
4202                                        continue;
4203                                }
4204                                $cached = $this->cached_events[$v];
4205                                $this->cached_events[$v] = array();
4206                                while (list($g,$event) = each($cached))
4207                                {
4208                                        $end = date('Ymd',$this->maketime($event['end']));
4209                                        print_debug('EVENT',_debug_array($event,False));
4210                                        print_debug('start',$start);
4211                                        print_debug('v',$v);
4212
4213                                        if (!isset($already_moved[$event['id']]) || $event['recur_type'] && $v > $end)
4214                                        {
4215                                                $this->cached_events[$v][] = $event;
4216                                                $already_moved[$event['id']] = 1;
4217                                                print_debug('Event moved');
4218                                        }
4219                                }
4220                        }
4221                }
4222
4223                function get_dirty_entries($lastmod=-1)
4224                {
4225                        $events = false;
4226                        $event_ids = $this->so->cal->list_dirty_events($lastmod);
4227                        if(is_array($event_ids))
4228                        {
4229                                foreach($event_ids as $key => $id)
4230                                {
4231                                        $events[$id] = $this->so->cal->fetch_event($id);
4232                                }
4233                        }
4234                        unset($event_ids);
4235
4236                        $rep_event_ids = $this->so->cal->list_dirty_events($lastmod,$true);
4237                        if(is_array($rep_event_ids))
4238                        {
4239                                foreach($rep_event_ids as $key => $id)
4240                                {
4241                                        $events[$id] = $this->so->cal->fetch_event($id);
4242                                }
4243                        }
4244                        unset($rep_event_ids);
4245
4246                        return $events;
4247                }
4248
4249                function _debug_array($data)
4250                {
4251                        echo '<br>UI:';
4252                        _debug_array($data);
4253                }
4254
4255                /*!
4256                @function rejected_no_show
4257                @abstract checks if event is rejected from user and he's not the owner and dont want rejected
4258                @param $event to check
4259                @returns True if event should not be shown
4260                */
4261                function rejected_no_show($event)
4262                {
4263                        $ret = !$this->prefs['calendar']['show_rejected'] &&
4264                                $event['owner'] != $this->owner &&
4265                                $event['participants'][$this->owner] == 'R';
4266                        //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";
4267                        return $ret;
4268                }
4269
4270                /* This is called only by list_cals().  It was moved here to remove fatal error in php5 beta4 */
4271                function list_cals_add($id,&$users,&$groups)
4272                {
4273                        $name = $GLOBALS['phpgw']->common->grab_owner_name($id);
4274                        if (($type = $GLOBALS['phpgw']->accounts->get_type($id)) == 'g')
4275                        {
4276                                $arr = &$groups;
4277                        }
4278                        else
4279                        {
4280                                $arr = &$users;
4281                        }
4282                        $arr[$name] = Array(
4283                                'grantor' => $id,
4284                                'value'   => ($type == 'g' ? 'g_' : '') . $id,
4285                                'name'    => $name
4286                        );
4287                }
4288
4289                /*!
4290                @function list_cals
4291                @abstract generate list of user- / group-calendars for the selectbox in the header
4292                @returns alphabeticaly sorted array with groups first and then users
4293                */
4294                function list_cals()
4295                {
4296                        $users = $groups = array();
4297                        foreach($this->grants as $id => $rights)
4298                        {
4299                                $this->list_cals_add($id,$users,$groups);
4300                        }
4301                       
4302                        //by JakJr, melhora de performance na abertura da agenda
4303                        /*if ($memberships = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']))
4304                        {
4305                                foreach($memberships as $group_info)
4306                                {
4307                                        $this->list_cals_add($group_info['account_id'],$users,$groups);
4308
4309                                        if ($account_perms = $GLOBALS['phpgw']->acl->get_ids_for_location($group_info['account_id'],PHPGW_ACL_READ,'calendar'))
4310                                        {
4311                                                foreach($account_perms as $id)
4312                                                {
4313                                                        $this->list_cals_add($id,$users,$groups);
4314                                                }
4315                                        }
4316                                }
4317                        }*/
4318                        uksort($users,'strnatcasecmp');
4319                        uksort($groups,'strnatcasecmp');
4320
4321                        return $users + $groups;        // users first and then groups, both alphabeticaly
4322                }
4323
4324          function translate($key,$vars=false, $not_found='*' )
4325          {
4326            if ($this->async)
4327              return $GLOBALS['phpgw']->translation->translate_async($key, $vars);
4328            return lang($key, $vars);
4329          }
4330
4331                /*!
4332                @function event2array
4333                @abstract create array with name, translated name and readable content of each attributes of an event
4334                @syntax event2array($event,$sep='<br>')
4335                @param $event event to use
4336                @returns array of attributes with fieldname as key and array with the 'field'=translated name \
4337                        'data' = readable content (for participants this is an array !)
4338                */
4339                function event2array($event)
4340                {
4341                       
4342                       
4343                  $var['title'] = Array(
4344                                'field'         => $this->translate('Title'),
4345                                'data'          => $event['title']
4346                        );
4347
4348                        // Some browser add a \n when its entered in the database. Not a big deal
4349                        // this will be printed even though its not needed.
4350                        $var['description'] = Array(
4351                                'field' => $this->translate('Description'),
4352                                'data'  => $event['description']
4353                        );
4354
4355                        $var['ex_participants'] = Array(
4356                                'field' => $this->translate('External Participants'),
4357                                'data'  => $event['ex_participants']
4358                        );
4359                       
4360                        $cats = Array();
4361                        $this->cat->categories($this->bo->owner,'calendar');
4362                        if(strpos($event['category'],','))
4363                        {
4364                                $cats = explode(',',$event['category']);
4365                        }
4366                        else
4367                        {
4368                                $cats[] = $event['category'];
4369                        }
4370                        foreach($cats as $cat_id)
4371                        {
4372                                list($cat) = $this->cat->return_single($cat_id);
4373                                $cat_string[] = $cat['name'];
4374                        }
4375                        $var['category'] = Array(
4376                                'field' => $this->translate('Category'),
4377                                'data'  => implode(', ',$cat_string)
4378                        );
4379
4380                        $var['location'] = Array(
4381                                'field' => $this->translate('Location'),
4382                                'data'  => $event['location']
4383                        );
4384
4385                        $var['startdate'] = Array(
4386                                'field' => $this->translate('Start Date/Time'),
4387                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset),
4388                        );
4389
4390                        $var['enddate'] = Array(
4391                                'field' => $this->translate('End Date/Time'),
4392                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset)
4393                        );
4394
4395                        $pri = Array(
4396                                1       => lang('Low'),
4397                                2       => lang('Normal'),
4398                                3       => lang('High')
4399                        );
4400                        $var['priority'] = Array(
4401                                'field' => lang('Priority'),
4402                                'data'  => $pri[$event['priority']]
4403                        );
4404
4405                        $owner = $event['owner'];
4406
4407                        $owner_name = ( $owner === -2 )? $event['organizer'] : $GLOBALS['phpgw']->common->grab_owner_name( $owner );
4408
4409                        $var['owner'] = Array(
4410                                'field' => lang('Created By'),
4411                                'data'  => $owner_name
4412                        );
4413
4414                        $var['updated'] = Array(
4415                                'field' => lang('Updated'),
4416                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['modtime']) - $GLOBALS['phpgw']->datetime->tz_offset)
4417                        );
4418
4419                        if($event['public']){
4420                                $type = lang('Public');
4421                        }else if (!$event['public'] && $event['type'] == 'E'){
4422                                $type = lang('Restrict');
4423                        }else{
4424                                $type = lang('Private');
4425                        }
4426
4427                        $var['access'] = Array(
4428                                'field' => lang('Access'),
4429                                'data'  => $type
4430                        );
4431
4432                        if(@isset($event['groups'][0]))
4433                        {
4434                                $cal_grps = '';
4435                                for($i=0;$i<count($event['groups']);$i++)
4436                                {
4437                                        if($GLOBALS['phpgw']->accounts->exists($event['groups'][$i]))
4438                                        {
4439                                                $cal_grps .= ($i>0?'<br>':'').$GLOBALS['phpgw']->accounts->id2name($event['groups'][$i]);
4440                                        }
4441                                }
4442
4443                                $var['groups'] = Array(
4444                                        'field' => lang('Groups'),
4445                                        'data'  => $cal_grps
4446                                );
4447                        }
4448
4449                        $participants = array();
4450                        foreach($event['participants'] as $user => $short_status)
4451                        {
4452                                if($GLOBALS['phpgw']->accounts->exists($user))
4453                                {
4454                                        $participants[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user).' ('.$this->get_long_status($short_status).')';
4455                                }
4456                        }
4457                        $var['participants'] = Array(
4458                                'field' => $this->translate('Participants'),
4459                                'data'  => $participants
4460                        );
4461
4462                        // Repeated Events
4463                        if($event['recur_type'] != MCAL_RECUR_NONE)
4464                        {
4465                                $str = lang($this->rpt_type[$event['recur_type']]);
4466
4467                                $str_extra = array();
4468                                if ($event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['year'] != 0)
4469                                {
4470                                        $recur_end = $this->maketime($event['recur_enddate']);
4471                                        if($recur_end != 0)
4472                                        {
4473                                                $recur_end -= $GLOBALS['phpgw']->datetime->tz_offset;
4474                                                $str_extra[] = lang('ends').': '.lang($GLOBALS['phpgw']->common->show_date($recur_end,'l')).', '.$this->long_date($recur_end).' ';
4475                                        }
4476                                }
4477                                // only weekly uses the recur-data (days) !!!
4478                                if($event['recur_type'] == MCAL_RECUR_WEEKLY)
4479                                {
4480                                        $repeat_days = array();
4481                                        foreach ($this->rpt_day as $mcal_mask => $dayname)
4482                                        {
4483                                                if ($event['recur_data'] & $mcal_mask)
4484                                                {
4485                                                        $repeat_days[] = lang($dayname);
4486                                                }
4487                                        }
4488                                        if(count($repeat_days))
4489                                        {
4490                                                $str_extra[] = lang('days repeated').': '.implode(', ',$repeat_days);
4491                                        }
4492                                }
4493                                if($event['recur_interval'] != 0)
4494                                {
4495                                        $str_extra[] = lang('Interval').': '.$event['recur_interval'];
4496                                }
4497
4498                                if(count($str_extra))
4499                                {
4500                                        $str .= ' ('.implode(', ',$str_extra).')';
4501                                }
4502
4503                                $var['recure_type'] = Array(
4504                                        'field' => lang('Repetition'),
4505                                        'data'  => $str,
4506                                );
4507                        }
4508
4509                        if (!isset($this->fields))
4510                        {
4511                                $this->custom_fields = CreateObject('calendar.bocustom_fields');
4512                                $this->fields = &$this->custom_fields->fields;
4513                                $this->stock_fields = &$this->custom_fields->stock_fields;
4514                        }
4515                        foreach($this->fields as $field => $data)
4516                        {
4517                                if (!$data['disabled'])
4518                                {
4519                                        if (isset($var[$field]))
4520                                        {
4521                                                $sorted[$field] = $var[$field];
4522                                        }
4523                                        elseif (!isset($this->stock_fields[$field]) && strlen($event[$field]))  // Custom field
4524                                        {
4525                                                $lang = lang($name = substr($field,1));
4526                                                $sorted[$field] = array(
4527                                                        'field' => $lang == $name.'*' ? $name : $lang,
4528                                                        'data'  => $event[$field]
4529                                                );
4530                                        }
4531                                }
4532                                unset($var[$field]);
4533                        }
4534                        foreach($var as $name => $v)
4535                        {
4536                                $sorted[$name] = $v;
4537
4538                        }
4539                        return $sorted;
4540                }
4541
4542                /*!
4543                @function check_set_default_prefs
4544                @abstract sets the default prefs, if they are not already set (on a per pref. basis)
4545                @note It sets a flag in the app-session-data to be called only once per session
4546                */
4547                function check_set_default_prefs()
4548                {
4549                        if (($set = $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar')))
4550                        {
4551                                return;
4552                        }
4553                        $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar','set');
4554
4555                        $default_prefs = $GLOBALS['phpgw']->preferences->default['calendar'];
4556
4557                        $subject = $this->translate('Calendar Event') . ' - $$action$$: $$startdate$$ $$title$$'."\n";
4558                        $defaults = array(
4559                                'defaultcalendar' => 'week',
4560                                'mainscreen_showevents' => '0',
4561                                'summary'         => 'no',
4562                                'receive_updates' => 'no',
4563                                'update_format'   => 'extended',        // leave it to extended for now, as iCal kills the message-body
4564                                'notifyAdded'     => $subject . $this->translate ('You have a meeting scheduled for %1',array('$$startdate$$')),
4565                                'notifyCanceled'  => $subject . $this->translate ('Your meeting scheduled for %1 has been canceled',array('$$startdate$$')),
4566                                'notifyModified'  => $subject . $this->translate ('Your meeting that had been scheduled for %1 has been rescheduled to %2',array('$$olddate$$','$$startdate$$')),
4567                                'notifyResponse'  => $subject . $this->translate ('On %1 %2 %3 your meeting request for %4', array('$$date$$','$$fullname$$','$$action$$','$$startdate$$')),
4568                                'notifyAlarm'     => $this->translate('Alarm for %1 at %2 in %3',array('$$title$$','$$startdate$$','$$location$$')) . "\n" . $this->translate('Here is your requested alarm.'),
4569                                'show_rejected'   => '0',
4570                                'hide_event_conflict'   => '0',
4571                                'display_status'  => '1',
4572                                'weekdaystarts'   => 'Monday',
4573                                'workdaystarts'   => '9',
4574                                'workdayends'     => '17',
4575                                'interval'        => '30',
4576                                'defaultlength'   => '60',
4577                                'planner_start_with_group' => $GLOBALS['phpgw']->accounts->name2id('Default'),
4578                                'planner_intervals_per_day'=> '4',
4579                                'defaultfilter'   => 'all',
4580                                'default_private' => '0',
4581                                'display_minicals'=> '1',
4582                                'print_black_white'=>'0'
4583                        );
4584                        foreach($defaults as $var => $default)
4585                        {
4586                                if (!isset($default_prefs[$var]) || $default_prefs[$var] == '')
4587                                {
4588                                        $GLOBALS['phpgw']->preferences->add('calendar',$var,$default,'default');
4589                                        $need_save = True;
4590                                }
4591                        }
4592                        if ($need_save)
4593                        {
4594                                $prefs = $GLOBALS['phpgw']->preferences->save_repository(False,'default');
4595                                $this->prefs['calendar'] = $prefs['calendar'];
4596                        }
4597                        if ($this->prefs['calendar']['send_updates'] && !isset($this->prefs['calendar']['receive_updates']))
4598                        {
4599                                $this->prefs['calendar']['receive_updates'] = $this->prefs['calendar']['send_updates'];
4600                                $GLOBALS['phpgw']->preferences->add('calendar','receive_updates',$this->prefs['calendar']['send_updates']);
4601                                $GLOBALS['phpgw']->preferences->delete('calendar','send_updates');
4602                                $prefs = $GLOBALS['phpgw']->preferences->save_repository();
4603                        }
4604                }
4605
4606                // return array with all infolog categories (for xmlrpc)
4607                function categories($complete = False)
4608                {
4609                        return $GLOBALS['server']->categories($complete);
4610                }
4611        }
4612?>
Note: See TracBrowser for help on using the repository browser.