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

Revision 5316, 162.9 KB checked in by cristiano, 12 years ago (diff)

Ticket #2423 - Trocar chamada da variável rootPath

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