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

Revision 2, 104.0 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

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