source: branches/2.2/calendar/inc/class.bocalendar.inc.php @ 3728

Revision 3728, 133.2 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #1479 - Evento com repetição não critica conflito.

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