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

Revision 36, 108.4 KB checked in by niltonneto, 17 years ago (diff)

* empty log message *

  • 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        function create_vcard($event)
2498        {
2499                // It translates int to string
2500                if ( $event[end][month] < 10 )
2501                        $end_event_month="0".$event[end][month];
2502                else
2503                        $end_event_month=$event[end][month];
2504                if ( $event[start][month] < 10 )
2505                        $start_event_month="0".$event[start][month];
2506                else
2507                        $start_event_month=$event[start][month];
2508                if ( $event[end][mday] < 10 )
2509                        $end_event_day="0".$event[end][mday];
2510                else
2511                        $end_event_day=$event[end][mday];
2512                if ( $event[start][mday] < 10 )
2513                        $start_event_day="0".$event[start][mday];
2514                else
2515                        $start_event_day=$event[start][mday];
2516                if ( $event[start][hour] < 10)
2517                        $start_event_hour="0".$event[start][hour];
2518                else
2519                        $start_event_hour=$event[start][hour];
2520                if ( $event[end][hour] < 10)
2521                        $end_event_hour="0".$event[end][hour];
2522                else
2523                        $end_event_hour=$event[end][hour];
2524                       
2525                if ( $event[start][min] < 10)
2526                        $start_event_min="0".$event[start][min];
2527                else
2528                        $start_event_min=$event[start][min];
2529                if ( $event[end][min] < 10)
2530                        $end_event_min="0".$event[end][min];
2531                else
2532                        $end_event_min=$event[end][min];       
2533       
2534                $tmpattach="BEGIN:VCALENDAR\n"
2535                ."PRODID:-//Expresso Livre//Calendar//EN\n"
2536                ."VERSION:1.0\n"
2537                ."BEGIN:VEVENT\n"
2538                ."DTSTART:".$event[start][year].$start_event_month.$start_event_day."T".$start_event_hour.$start_event_min."00Z\n"
2539                ."DTEND:".$event[end][year].$end_event_month.$end_event_day."T".$end_event_hour.$end_event_min."00Z\n"
2540                ."UID:Expresso-".$event[id].$event[uid]."\n"
2541                ."LAST-MODIFIED:".time()."\n"
2542                ."DESCRIPTION:".$event[description]."\n"
2543                ."SUMMARY:".$event[title]."\n"
2544                ."LOCATION:".$event[location]."\n"
2545                ."END:VEVENT"."\n"
2546                ."END:VCALENDAR\n";
2547                return $tmpattach;
2548}
2549
2550                /*!
2551                @function send_update
2552                @abstract sends update-messages to certain participants of an event
2553                @syntax send_update($msg_type,$to_notify,$old_event,$new_event=False)
2554                @param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
2555                @param $to_notify array with numerical user-ids as keys (!) (value is not used)
2556                @param $old_event Event before the change
2557                @param $new_event Event after the change
2558                */
2559                function send_update($msg_type,$to_notify,$old_event,$new_event=False,$user=False)
2560                {
2561                       
2562                        //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";
2563                        if (!is_array($to_notify))
2564                        {
2565                                $to_notify = array();
2566                        }
2567                        $owner = $old_event ? $old_event['owner'] : $new_event['owner'];
2568                        if ($owner && !isset($to_notify[$owner]) && $msg_type != MSG_ALARM)
2569                        {
2570                                $to_notify[$owner] = 'owner';   // always include the event-owner
2571                        }
2572                        $version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
2573
2574                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
2575                        $sender = $GLOBALS['phpgw_info']['user']['email'];
2576
2577                        $temp_tz_offset = $this->prefs['common']['tz_offset'];
2578                        $temp_timeformat = $this->prefs['common']['timeformat'];
2579                        $temp_dateformat = $this->prefs['common']['dateformat'];
2580
2581                        $tz_offset = ((60 * 60) * (int)$temp_tz_offset);
2582
2583                        if($old_event != False)
2584                        {
2585                                $t_old_start_time = $this->maketime($old_event['start']);
2586                                if($t_old_start_time < (time() - 86400))
2587                                {
2588                                        return False;
2589                                }
2590                        }
2591
2592                        $temp_user = $GLOBALS['phpgw_info']['user'];
2593
2594                        if (!$user)
2595                        {
2596                                $user = $this->owner;
2597                        }
2598                        $GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
2599
2600                        $event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
2601                        if($old_event != False)
2602                        {
2603                                $old_starttime = $t_old_start_time - $GLOBALS['phpgw']->datetime->tz_offset;
2604                        }
2605                        $starttime = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
2606                        $endtime   = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
2607
2608                        switch($msg_type)
2609                        {
2610                                case MSG_DELETED:
2611                                        $action = lang('Canceled');
2612                                        $msg = 'Canceled';
2613                                        $msgtype = '"calendar";';
2614                                        $method = 'cancel';
2615                                        $typesend = 1;
2616                                        break;
2617                                case MSG_MODIFIED:
2618                                        $action = lang('Modified');
2619                                        $msg = 'Modified';
2620                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
2621                                        $method = 'request';
2622                                        $typesend = 2;
2623                                        break;
2624                                case MSG_ADDED:
2625                                        $action = lang('Added');
2626                                        $msg = 'Added';
2627                                        $msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
2628                                        $method = 'request';
2629                                        $typesend = 3;
2630                                        break;
2631                                case MSG_REJECTED:
2632                                        $action = lang('Rejected');
2633                                        $msg = 'Response';
2634                                        $msgtype = '"calendar";';
2635                                        $method = 'reply';
2636                                        $typesend = 4;
2637                                        break;
2638                                case MSG_TENTATIVE:
2639                                        $action = lang('Tentative');
2640                                        $msg = 'Response';
2641                                        $msgtype = '"calendar";';
2642                                        $method = 'reply';
2643                                        $typesend = 5;
2644                                        break;
2645                                case MSG_ACCEPTED:
2646                                        $action = lang('Accepted');
2647                                        $msg = 'Response';
2648                                        $msgtype = '"calendar";';
2649                                        $method = 'reply';
2650                                        $typesend = 6;
2651                                        break;
2652                                case MSG_ALARM:
2653                                        $action = lang('Alarm');
2654                                        $msg = 'Alarm';
2655                                        $msgtype = '"calendar";';
2656                                        $method = 'publish';    // duno if thats right
2657                                        $typesend = 7;
2658                                        break;
2659                                default:
2660                                        $method = 'publish';
2661                                        $typesend = 8;
2662                        }
2663                        $notify_msg = $this->prefs['calendar']['notify'.$msg];
2664                        if (empty($notify_msg))
2665                        {
2666                                $notify_msg = $this->prefs['calendar']['notifyAdded'];  // use a default
2667                        }
2668                        $details = array(                       // event-details for the notify-msg
2669                                'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
2670                                'action'      => $action,
2671                        );
2672                        $event_arr = $this->event2array($event);
2673                        foreach($event_arr as $key => $val)
2674                        {
2675                                $details[$key] = $val['data'];
2676                        }
2677                       
2678                        $details['participants'] = implode("\n",$details['participants']);
2679
2680                        $details['link'] = $GLOBALS['phpgw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uicalendar.view&cal_id='.$event['id'];
2681                        // if url is only a path, try guessing the rest ;-)
2682                        if ($GLOBALS['phpgw_info']['server']['webserver_url'][0] == '/')
2683                        {
2684                                $details['link'] = ($GLOBALS['phpgw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
2685                                        ($GLOBALS['phpgw_info']['server']['hostname'] ? $GLOBALS['phpgw_info']['server']['hostname'] : 'localhost').
2686                                        $details['link'];
2687                        }
2688
2689                        /*if(!is_object($GLOBALS['phpgw']->send))
2690                        {
2691                                $GLOBALS['phpgw']->send = CreateObject('phpgwapi.send');
2692                        }*/
2693                //      $send = &$GLOBALS['phpgw']->send;
2694                       
2695                        //Seta o email usando phpmailer
2696                        define('PHPGW_INCLUDE_ROOT','../');     
2697                        define('PHPGW_API_INC','../phpgwapi/inc');     
2698                        include_once(PHPGW_API_INC.'/class.phpmailer.inc.php');
2699                        $mail = new PHPMailer();
2700                        $mail->IsSMTP();
2701                        $mail->Host = $_SESSION['phpgw_info']['expressomail']['email_server']['smtpServer'];
2702                        $mail->Port = $_SESSION['phpgw_info']['expressomail']['email_server']['smtpPort'];
2703                        $mail->From = $_SESSION['phpgw_info']['expressomail']['user']['email'];
2704                        $mail->FromName = $_SESSION['phpgw_info']['expressomail']['user']['fullname'];
2705                        $mail->IsHTML(true);
2706                       
2707                        // Aqui é enviado o email
2708                        foreach($to_notify as $userid => $statusid)
2709                        {
2710                                $mail->ClearAllRecipients();
2711                                $mail->ClearAttachments();
2712                               
2713                                $userid = (int)$userid;
2714
2715                                if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g')
2716                                {
2717                                        continue;       // dont notify rejected participants
2718                                }
2719                                if($userid != $GLOBALS['phpgw_info']['user']['account_id'] ||  $msg_type == MSG_ALARM)
2720                                {
2721                                        print_debug('Msg Type',$msg_type);
2722                                        print_debug('UserID',$userid);
2723
2724                                        $preferences = CreateObject('phpgwapi.preferences',$userid);
2725                                        $part_prefs = $preferences->read_repository();
2726
2727                                        if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event))
2728                                        {
2729                                                continue;
2730                                        }
2731                                        $GLOBALS['phpgw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
2732                                        $details['to-fullname'] = $GLOBALS['phpgw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
2733
2734                                        $to = $preferences->email_address($userid);
2735                                       
2736                                        if (empty($to) || $to[0] == '@' || $to[0] == '$')       // we have no valid email-address
2737                                        {
2738                                                //echo "<p>bocalendar::send_update: Empty email adress for user '".$details['to-fullname']."' ==> ignored !!!</p>\n";
2739                                                continue;
2740                                        }
2741                                        print_debug('Email being sent to',$to);
2742
2743                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
2744                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
2745                                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
2746
2747                                        $GLOBALS['phpgw']->datetime->tz_offset = ((60 * 60) * (int)$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']);
2748
2749                                        if($old_starttime)
2750                                        {
2751                                                $details['olddate'] = $GLOBALS['phpgw']->common->show_date($old_starttime);
2752                                        }
2753                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
2754                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
2755                                       
2756                                       
2757                                        list($subject,$body1) = split("\n",$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
2758                                       
2759                                        switch($part_prefs['calendar']['update_format'])
2760                                        {
2761                                                case  'extended':
2762                                                        //$body .= "\n\n".lang('Event Details follow').":\n";
2763                                                        $body = '';
2764                                                        $body .= "<br>".lang('Event Details follow')." :: ";
2765                                                        foreach($event_arr as $key => $val)
2766                                                        {
2767                                                                // titulo
2768                                                                if($key =='title')
2769                                                                {
2770                                                                        $var1 = $val['field'];
2771                                                                        $vardata1 = $details[$key];
2772                                                                }
2773                                                                //descricao
2774                                                                if($key =='description')
2775                                                                {
2776                                                                        $var2 = $val['field'];
2777                                                                        $vardata2 = $details[$key];
2778                                                                }
2779                                                                //dt inicio
2780                                                                if($key =='startdate')
2781                                                                {
2782                                                                        switch(trim($part_prefs['common']['dateformat']))
2783                                                                        {
2784                                                                               
2785                                                                                case ($part_prefs['common']['dateformat'] === "m/d/Y" || $part_prefs['common']['dateformat'] === "m-d-Y" || $part_prefs['common']['dateformat'] === "m.d.Y"):
2786                                                                                        $var3 = $val['field'];
2787                                                                                        $vardata3 = $details[$key];
2788                                                                                        $newmounth3 = substr($vardata3,0,2);
2789                                                                                        $newday3 = substr($vardata3,3,2);
2790                                                                                        $newyear3 = substr($vardata3,6,4);
2791                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
2792                                                                                        break;
2793                                                                                       
2794                                                                                case    ($part_prefs['common']['dateformat'] === "Y/d/m" || $part_prefs['common']['dateformat'] === "Y-d-m" || $part_prefs['common']['dateformat'] === "Y.d.m"):
2795
2796                                                                                        $var3 = $val['field'];
2797                                                                                        $vardata3 = $details[$key];
2798                                                                                        $newyear3 = substr($vardata3,0,4);
2799                                                                                        $newday3 = substr($vardata3,5,2);
2800                                                                                        $newmounth3 = substr($vardata3,8,2);
2801                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
2802                                                                                        break;
2803
2804                                                                                case ($part_prefs['common']['dateformat'] === "Y/m/d" || $part_prefs['common']['dateformat'] === "Y-m-d" || $part_prefs['common']['dateformat'] === "Y.m.d"):
2805
2806                                                                                        $var3 = $val['field'];
2807                                                                                        $vardata3 = $details[$key];
2808                                                                                        $newyear3 = substr($vardata3,0,4);
2809                                                                                        $newmounth3 = substr($vardata3,5,2);
2810                                                                                        $newday3 = substr($vardata3,8,2);
2811                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
2812                                                                                        break;
2813
2814                                                                                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"):
2815                                                                               
2816                                                                                        $var3 = $val['field'];
2817                                                                                        $vardata3 = $details[$key];
2818                                                                                        $newday3 = substr($vardata3,0,2);
2819                                                                                        $newmounth3 = substr($vardata3,3,2);
2820                                                                                        $newyear3 = substr($vardata3,6,4);
2821                                                                                        $newall3 =$newyear3.$newmounth3.$newday3;
2822                                                                                        break;
2823                                                                       
2824                                                                        }
2825                                                                       
2826                                                                }
2827                                                                //dt final
2828                                                                if($key =='enddate')
2829                                                                {
2830                                                                        $var4 = $val['field'];
2831                                                                        $vardata4 = $details[$key];
2832                                                                }
2833                                                                //localizacao
2834                                                                if($key =='location')
2835                                                                {
2836                                                                        $var8 = $val['field'];
2837                                                                        $vardata8 = $details[$key];
2838                                                                }
2839                                                                //participantes
2840                                                                if($key =='participants')
2841                                                                {
2842                                                                        $var5 = $val['field'];
2843                                                                        foreach($val['data'] as $NewKey => $NewVal)
2844                                                                        {
2845                                                                                //Research inside of ldap ( Pesquisa dentro do ldap )
2846                                                                                $newvalue = $this->so->search_uidNumber($to);
2847                                                                                foreach($newvalue as $tmp)
2848                                                                                {
2849                                                                                        $tmpmail = $tmp['mail'][0];
2850                                                                                        $tmpuid = $tmp['uidnumber'][0];
2851                                                                                        if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
2852                                                                                        {
2853                                                                                                        if($typesend == 3)
2854                                                                                                        {
2855
2856                                                                                                                $lang1 = lang("To See Commitment");
2857                                                                                                                $varbuttom = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id=$event[id]&date=$newall3' method='POST'>
2858                                                                                                                                                                  <input type='submit' value='$lang1'>
2859                                                                                                                                                                   </form>";
2860                                                                                                                $lang2 = lang("To accept");
2861                                                                                                                $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\")'>";
2862
2863                                                                                                                $lang3 = lang("To reject");
2864                                                                                                                $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\")'>";
2865                                                                                                               
2866                                                                                                                $lang4 = lang("Alarm");
2867                                                                                                                $varbuttom3 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uialarm.manager method='POST'>
2868                                                                                                                                                                  <input type='submit' value='$lang4'>
2869                                                                                                                                                                  <input type='hidden' name='cal_id' value=$event[id]>
2870                                                                                                                                                                   </form>";
2871                                                                                                        }
2872                                                                                                        else
2873                                                                                                        {
2874                                                                                                                        $varbuttom  = "";
2875                                                                                                                        $varbuttom1 = "";
2876                                                                                                                        $varbuttom2 = "";
2877                                                                                                                        $varbuttom3 = "";
2878                                                                                                        }
2879                                                                                        }
2880                                                                                        // It only mounts variavel with the name of the participants of the list ( Monta a variavel somente com o nome dos participantes da lista)
2881                                                                                        if($typesend == 3)
2882                                                                                        {
2883                                                                                                list($tmpvardata5,$tmp2vardata5) = explode("(",$NewVal);
2884                                                                                                $vardata5 = $tmpvardata5."<br>";
2885                                                                                        }
2886                                                                                        else
2887                                                                                        {
2888                                                                                                $vardata5 = $NewVal."<br>";
2889                                                                                        }
2890                                                                               
2891                                                                                }
2892                                                                                $vardata6 .= $vardata5;
2893                                                                                unset($vardata5);
2894                                                                        }
2895                                                                }               
2896                                                        }
2897                                                        //To mount the message as text/html (Para montar a mensagem como text/html - /phpgwapi/inc/class.send.inc.php )
2898                                                        $content_type = "text/html";
2899                                                        //It mounts the body of the message (Monta o corpo da mensagem)
2900                                                       
2901                                                        // A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
2902                                                        define ("PHPGW_APP_TPL",PHPGW_API_INC . "/../../calendar/templates/celepar");
2903                                                       
2904                                                        $body = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);
2905                                                        $body->set_file(Array('calendar' => 'body_email.tpl'));
2906                                                        $body->set_block('calendar','list');
2907                                                        $var = Array(
2908                                                                'script'                        => $script,
2909                                                                'subject'                       => $body1,
2910                                                                'var1'                          => $var1,
2911                                                                'vardata1'                      => $vardata1,
2912                                                                'var2'                          => $var2,
2913                                                                'vardata2'                      => $vardata2,
2914                                                                'var3'                          => $var3,
2915                                                                'vardata3'                      => $vardata3,
2916                                                                'var4'                          => $var4,
2917                                                                'vardata4'                      => $vardata4,
2918                                                                'var5'                          => $var5,
2919                                                                'vardata6'                      => $vardata6,
2920                                                                'var8'                          => $var8,
2921                                                                'vardata8'                      => $vardata8,                                                   
2922                                                                'varbuttom'                     => $varbuttom,
2923                                                                'varbuttom1'            => $varbuttom1,
2924                                                                'varbuttom2'            => $varbuttom2,
2925                                                                'varbuttom3'            => $varbuttom3
2926                                                               
2927                                                        );
2928                                                        $body->set_var($var);
2929                                                        $tmpbody = $body->fp('out','list');
2930                                                                                                               
2931                                                        break;
2932
2933                                                case 'ical':
2934                                                        $content_type = "calendar; method=$method; name=calendar.ics";
2935/*                                                      if ($body != '')
2936                                                        {
2937                                                                $boundary = '----Message-Boundary';
2938                                                                $body .= "\n\n\n$boundary\nContent-type: text/$content_type\n".
2939                                                                        "Content-Disposition: inline\nContent-transfer-encoding: 7BIT\n\n";
2940                                                                $content_type = '';
2941                                                        }
2942*/
2943                                                        $body = ExecMethod('calendar.boicalendar.export',array(
2944                                                                'l_event_id'  => $event['id'],
2945                                                                'method'      => $method,
2946                                                                'chunk_split' => False
2947                                                        ));
2948                                                        break;
2949                                        }
2950                                        $mail->AddAddress($to);
2951                                        $mail->Body = $tmpbody;
2952                                        $mail->From = $sender;
2953                                        $mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
2954                                        $mail->Sender = $mail->From;
2955                                        $mail->SenderName = $mail->FromName;
2956                                        $mail->Subject = $subject;
2957                                       
2958                                       
2959                                        //It sends email for the participants ( Envia email para os participantes)
2960                                        if(!$mail->Send())
2961                                        {
2962                                               
2963                                                $returncode=false;
2964                                        }
2965                                        else
2966                                        {
2967                                                $returncode=true;
2968                                        }
2969                                                               
2970                                        //$returncode = $send->msg('email',$to,$subject,$tmpbody,''/*$msgtype*/,'','','',$sender, $content_type/*,$boundary*/);
2971
2972                               
2973                                        unset($vardata5);
2974                                        unset($vardata6);
2975                                        if (!$returncode)       // not nice, but better than failing silently
2976                                        {
2977                                                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";
2978                                                echo '<i>'.$mail->ErrorInfo."</i><br>\n";
2979                                                echo lang('This is mostly caused by a not or wrongly configured SMTP server. Notify your administrator.')."</p>\n";
2980                                                echo '<p>'.lang('Click %1here%2 to return to the calendar.','<a href="'.$GLOBALS['phpgw']->link('/calendar/').'">','</a>')."</p>\n";
2981                                        }
2982                                }
2983                        }
2984                        if(count($to_notify) && $this->ex_participants){
2985                                $var = explode(",",trim($this->ex_participants));
2986                                $to = array();
2987                                if(!$subject) {
2988                                        $details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
2989                                        $details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
2990                                        list($subject,$body1) = split("\n",$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
2991                                }
2992                                foreach($var as $index => $ex_participant){
2993                                        $ex_participant = trim($ex_participant);
2994                                        $ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
2995                                                if($ex_participant)
2996                                                        $to[] = $ex_participant;
2997                                }               
2998                                foreach($to as $i => $to_array)
2999                                        $mail->AddAddress($to_array);
3000                                $_body = explode("<hr size='1' width='100%'>",$tmpbody);
3001                                $tmpbody = $_body[0];
3002                                $tmpbody.= "<b>".lang("external participants").":: </b> ".htmlentities($this->ex_participants);
3003                                $tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
3004                                $tmpbody.= "<br>".lang("Start date").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
3005                                $tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
3006                                .lang("This message was sent by server. You must send a message to sender to confirm this event")."<br>"
3007                                .lang("This is an external event. Even if it added to your expresso its can be changed any time at all")."</font><br>";
3008                               
3009                                if ($GLOBALS['bocalendar']->so->cal->event[start][month] > 10)
3010                                        $event_month=$GLOBALS['bocalendar']->so->cal->event[start][month];
3011                                else
3012                                        $event_month="0".$GLOBALS['bocalendar']->so->cal->event[start][month];
3013                                $tmpbody .="<a href='../index.php?menuaction=calendar.uicalendar.add&date="
3014                                .$GLOBALS['bocalendar']->so->cal->event[start][year]
3015                                .$event_month
3016                                .$GLOBALS['bocalendar']->so->cal->event[start][mday]
3017                                ."&hour=".$GLOBALS['bocalendar']->so->cal->event[start][hour]
3018                                ."&minute=".$GLOBALS['bocalendar']->so->cal->event[start][min]
3019                                ."&title=".$GLOBALS['bocalendar']->so->cal->event['title']
3020                                ."&description=".$GLOBALS['bocalendar']->so->cal->event['description']
3021                                ."&location=".$GLOBALS['bocalendar']->so->cal->event['location']."'>"
3022                                ."<h2>".lang("Add to my expresso")."</h2>";
3023                               
3024                                //attach extern vcard                   
3025                                // define('context','$GLOBALS.bocalendar.so.cal.event');
3026                                $tmpattach = $this->create_vcard($GLOBALS['bocalendar']->so->cal->event);
3027                                $tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
3028                                srand((double)microtime()*1000000);
3029                                $random_number = rand(100000000,999999999);
3030                                $newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
3031                                $filename = $tempdir . $newfilename;
3032                                $attach_fd = fopen($filename,"w+");
3033                                fwrite($attach_fd,$tmpattach);
3034                                $mail->AddAttachment($filename, "extern.vcard", "base64", "text/plain"); // "application/octet-stream"
3035                                fclose($attach_fd);
3036                                $mail->From = $sender;
3037                                $mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
3038                                $mail->Sender = $mail->From;
3039                                $mail->SenderName = $mail->FromName;
3040                                $mail->Subject = lang("External event from Expresso");
3041                                $mail->Body = $tmpbody;
3042                               
3043                                if(!$mail->Send())
3044                                {
3045                                        $returncode=false;
3046                                }
3047                                else
3048                                {
3049                                        $returncode=true;
3050                                }
3051                        }
3052
3053
3054                        if((is_int($this->user) && $this->user != $temp_user['account_id']) ||
3055                                (is_string($this->user) && $this->user != $temp_user['account_lid']))
3056                        {
3057                                $GLOBALS['phpgw_info']['user'] = $temp_user;
3058                        }
3059
3060                        $GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $temp_tz_offset;
3061                        $GLBOALS['phpgw']->datetime->tz_offset = ((60 * 60) * $temp_tz_offset);
3062                        $GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $temp_timeformat;
3063                        $GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
3064
3065                        return $returncode;
3066                }
3067
3068                function send_alarm($alarm)
3069                {
3070                        //echo "<p>bocalendar::send_alarm("; print_r($alarm); echo ")</p>\n";
3071                        $GLOBALS['phpgw_info']['user']['account_id'] = $this->owner = $alarm['owner'];
3072
3073                        if (!$alarm['enabled'] || !$alarm['owner'] || !$alarm['cal_id'] || !($event = $this->so->read_entry($alarm['cal_id'])))
3074                        {
3075                                return False;   // event not found
3076                        }
3077                        if ($alarm['all'])
3078                        {
3079                                $to_notify = $event['participants'];
3080                        }
3081                        elseif ($this->check_perms(PHPGW_ACL_READ,$event))      // checks agains $this->owner set to $alarm[owner]
3082                        {
3083                                $to_notify[$alarm['owner']] = 'A';
3084                        }
3085                        else
3086                        {
3087                                return False;   // no rights
3088                        }
3089                        return $this->send_update(MSG_ALARM,$to_notify,$event,False,$alarm['owner']);
3090                }
3091
3092                function get_alarms($event_id)
3093                {
3094                        return $this->so->get_alarm($event_id);
3095                }
3096
3097                function alarm_today($event,$today,$starttime)
3098                {
3099                        $found = False;
3100                        @reset($event['alarm']);
3101                        $starttime_hi = $GLOBALS['phpgw']->common->show_date($starttime,'Hi');
3102                        $t_appt['month'] =$GLOBALS['phpgw']->common->show_date($today,'m');
3103                        $t_appt['mday'] = $GLOBALS['phpgw']->common->show_date($today,'d');
3104                        $t_appt['year'] = $GLOBALS['phpgw']->common->show_date($today,'Y');
3105                        $t_appt['hour'] = $GLOBALS['phpgw']->common->show_date($starttime,'H');
3106                        $t_appt['min']  = $GLOBALS['phpgw']->common->show_date($starttime,'i');
3107                        $t_appt['sec']  = 0;
3108                        $t_time = $this->maketime($t_appt) - $GLOBALS['phpgw']->datetime->tz_offset;
3109                        $y_time = $t_time - 86400;
3110                        $tt_time = $t_time + 86399;
3111                        print_debug('T_TIME',$t_time.' : '.$GLOBALS['phpgw']->common->show_date($t_time));
3112                        print_debug('Y_TIME',$y_time.' : '.$GLOBALS['phpgw']->common->show_date($y_time));
3113                        print_debug('TT_TIME',$tt_time.' : '.$GLOBALS['phpgw']->common->show_date($tt_time));
3114                        while(list($key,$alarm) = each($event['alarm']))
3115                        {
3116                                if($alarm['enabled'])
3117                                {
3118                                        print_debug('TIME',$alarm['time'].' : '.$GLOBALS['phpgw']->common->show_date($alarm['time']).' ('.$event['id'].')');
3119                                        if($event['recur_type'] != MCAL_RECUR_NONE)   /* Recurring Event */
3120                                        {
3121                                                print_debug('Recurring Event');
3122                                                if($alarm['time'] > $y_time && $GLOBALS['phpgw']->common->show_date($alarm['time'],'Hi') < $starttime_hi && $alarm['time'] < $t_time)
3123                                                {
3124                                                        $found = True;
3125                                                }
3126                                        }
3127                                        elseif($alarm['time'] > $y_time && $alarm['time'] < $t_time)
3128                                        {
3129                                                $found = True;
3130                                        }
3131                                }
3132                        }
3133                        print_debug('Found',$found);
3134                        return $found;
3135                }
3136
3137                function prepare_recipients(&$new_event,$old_event)
3138                {
3139                        // Find modified and deleted users.....
3140                        while(list($old_userid,$old_status) = each($old_event['participants']))
3141                        {
3142                                if(isset($new_event['participants'][$old_userid]))
3143                                {
3144                                        print_debug('Modifying event for user',$old_userid);
3145                                        $this->modified[(int)$old_userid] = $new_status;
3146                                }
3147                                else
3148                                {
3149                                        print_debug('Deleting user from the event',$old_userid);
3150                                        $this->deleted[(int)$old_userid] = $old_status;
3151                                }
3152                        }
3153                        // Find new users.....
3154                        while(list($new_userid,$new_status) = each($new_event['participants']))
3155                        {
3156                                if(!isset($old_event['participants'][$new_userid]))
3157                                {
3158                                        print_debug('Adding event for user',$new_userid);
3159                                        $this->added[$new_userid] = 'U';
3160                                        $new_event['participants'][$new_userid] = 'U';
3161                                }
3162                        }
3163
3164                        if(count($this->added) > 0 || count($this->modified) > 0 || count($this->deleted) > 0)
3165                        {
3166                                if(count($this->added) > 0)
3167                                {
3168                                        $this->send_update(MSG_ADDED,$this->added,'',$new_event);
3169                                }
3170                                if(count($this->modified) > 0)
3171                                {
3172                                        $this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event);
3173                                }
3174                                if(count($this->deleted) > 0)
3175                                {
3176                                        $this->send_update(MSG_DELETED,$this->deleted,$old_event);
3177                                }
3178                        }
3179                }
3180
3181                function remove_doubles_in_cache($firstday,$lastday)
3182                {
3183                        $already_moved = Array();
3184                        for($v=$firstday;$v<=$lastday;$v++)
3185                        {
3186                                if (!$this->cached_events[$v])
3187                                {
3188                                        continue;
3189                                }
3190                                $cached = $this->cached_events[$v];
3191                                $this->cached_events[$v] = array();
3192                                while (list($g,$event) = each($cached))
3193                                {
3194                                        $end = date('Ymd',$this->maketime($event['end']));
3195                                        print_debug('EVENT',_debug_array($event,False));
3196                                        print_debug('start',$start);
3197                                        print_debug('v',$v);
3198
3199                                        if (!isset($already_moved[$event['id']]) || $event['recur_type'] && $v > $end)
3200                                        {
3201                                                $this->cached_events[$v][] = $event;
3202                                                $already_moved[$event['id']] = 1;
3203                                                print_debug('Event moved');
3204                                        }
3205                                }
3206                        }
3207                }
3208
3209                function get_dirty_entries($lastmod=-1)
3210                {
3211                        $events = false;
3212                        $event_ids = $this->so->cal->list_dirty_events($lastmod);
3213                        if(is_array($event_ids))
3214                        {
3215                                foreach($event_ids as $key => $id)
3216                                {
3217                                        $events[$id] = $this->so->cal->fetch_event($id);
3218                                }
3219                        }
3220                        unset($event_ids);
3221
3222                        $rep_event_ids = $this->so->cal->list_dirty_events($lastmod,$true);
3223                        if(is_array($rep_event_ids))
3224                        {
3225                                foreach($rep_event_ids as $key => $id)
3226                                {
3227                                        $events[$id] = $this->so->cal->fetch_event($id);
3228                                }
3229                        }
3230                        unset($rep_event_ids);
3231
3232                        return $events;
3233                }
3234
3235                function _debug_array($data)
3236                {
3237                        echo '<br>UI:';
3238                        _debug_array($data);
3239                }
3240
3241                /*!
3242                @function rejected_no_show
3243                @abstract checks if event is rejected from user and he's not the owner and dont want rejected
3244                @param $event to check
3245                @returns True if event should not be shown
3246                */
3247                function rejected_no_show($event)
3248                {
3249                        $ret = !$this->prefs['calendar']['show_rejected'] &&
3250                                $event['owner'] != $this->owner &&
3251                                $event['participants'][$this->owner] == 'R';
3252                        //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";
3253                        return $ret;
3254                }
3255
3256                /* This is called only by list_cals().  It was moved here to remove fatal error in php5 beta4 */
3257                function list_cals_add($id,&$users,&$groups)
3258                {
3259                        $name = $GLOBALS['phpgw']->common->grab_owner_name($id);
3260                        if (($type = $GLOBALS['phpgw']->accounts->get_type($id)) == 'g')
3261                        {
3262                                $arr = &$groups;
3263                        }
3264                        else
3265                        {
3266                                $arr = &$users;
3267                        }
3268                        $arr[$name] = Array(
3269                                'grantor' => $id,
3270                                'value'   => ($type == 'g' ? 'g_' : '') . $id,
3271                                'name'    => $name
3272                        );
3273                }
3274
3275                /*!
3276                @function list_cals
3277                @abstract generate list of user- / group-calendars for the selectbox in the header
3278                @returns alphabeticaly sorted array with groups first and then users
3279                */
3280                function list_cals()
3281                {
3282                        $users = $groups = array();
3283                        foreach($this->grants as $id => $rights)
3284                        {
3285                                $this->list_cals_add($id,$users,$groups);
3286                        }
3287                       
3288                        //by JakJr, melhora de performance na abertura da agenda
3289                        /*if ($memberships = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']))
3290                        {
3291                                foreach($memberships as $group_info)
3292                                {
3293                                        $this->list_cals_add($group_info['account_id'],$users,$groups);
3294
3295                                        if ($account_perms = $GLOBALS['phpgw']->acl->get_ids_for_location($group_info['account_id'],PHPGW_ACL_READ,'calendar'))
3296                                        {
3297                                                foreach($account_perms as $id)
3298                                                {
3299                                                        $this->list_cals_add($id,$users,$groups);
3300                                                }
3301                                        }
3302                                }
3303                        }*/
3304                        uksort($users,'strnatcasecmp');
3305                        uksort($groups,'strnatcasecmp');
3306
3307                        return $users + $groups;        // users first and then groups, both alphabeticaly
3308                }
3309
3310                /*!
3311                @function event2array
3312                @abstract create array with name, translated name and readable content of each attributes of an event
3313                @syntax event2array($event,$sep='<br>')
3314                @param $event event to use
3315                @returns array of attributes with fieldname as key and array with the 'field'=translated name \
3316                        'data' = readable content (for participants this is an array !)
3317                */
3318                function event2array($event)
3319                {
3320                        $var['title'] = Array(
3321                                'field'         => lang('Title'),
3322                                'data'          => $event['title']
3323                        );
3324
3325                        // Some browser add a \n when its entered in the database. Not a big deal
3326                        // this will be printed even though its not needed.
3327                        $var['description'] = Array(
3328                                'field' => lang('Description'),
3329                                'data'  => $event['description']
3330                        );
3331
3332                        $var['ex_participants'] = Array(
3333                                'field' => lang('External Participants'),
3334                                'data'  => $event['ex_participants']
3335                        );
3336
3337                        $cats = Array();
3338                        $this->cat->categories($this->bo->owner,'calendar');
3339                        if(strpos($event['category'],','))
3340                        {
3341                                $cats = explode(',',$event['category']);
3342                        }
3343                        else
3344                        {
3345                                $cats[] = $event['category'];
3346                        }
3347                        foreach($cats as $cat_id)
3348                        {
3349                                list($cat) = $this->cat->return_single($cat_id);
3350                                $cat_string[] = $cat['name'];
3351                        }
3352                        $var['category'] = Array(
3353                                'field' => lang('Category'),
3354                                'data'  => implode(', ',$cat_string)
3355                        );
3356
3357                        $var['location'] = Array(
3358                                'field' => lang('Location'),
3359                                'data'  => $event['location']
3360                        );
3361
3362                        $var['startdate'] = Array(
3363                                'field' => lang('Start Date/Time'),
3364                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset),
3365                        );
3366
3367                        $var['enddate'] = Array(
3368                                'field' => lang('End Date/Time'),
3369                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset)
3370                        );
3371
3372                        $pri = Array(
3373                                1       => lang('Low'),
3374                                2       => lang('Normal'),
3375                                3       => lang('High')
3376                        );
3377                        $var['priority'] = Array(
3378                                'field' => lang('Priority'),
3379                                'data'  => $pri[$event['priority']]
3380                        );
3381
3382                        $var['owner'] = Array(
3383                                'field' => lang('Created By'),
3384                                'data'  => $GLOBALS['phpgw']->common->grab_owner_name($event['owner'])
3385                        );
3386
3387                        $var['updated'] = Array(
3388                                'field' => lang('Updated'),
3389                                'data'  => $GLOBALS['phpgw']->common->show_date($this->maketime($event['modtime']) - $GLOBALS['phpgw']->datetime->tz_offset)
3390                        );
3391
3392                        $var['access'] = Array(
3393                                'field' => lang('Access'),
3394                                'data'  => $event['public'] ? lang('Public') : lang('Private')
3395                        );
3396
3397                        if(@isset($event['groups'][0]))
3398                        {
3399                                $cal_grps = '';
3400                                for($i=0;$i<count($event['groups']);$i++)
3401                                {
3402                                        if($GLOBALS['phpgw']->accounts->exists($event['groups'][$i]))
3403                                        {
3404                                                $cal_grps .= ($i>0?'<br>':'').$GLOBALS['phpgw']->accounts->id2name($event['groups'][$i]);
3405                                        }
3406                                }
3407
3408                                $var['groups'] = Array(
3409                                        'field' => lang('Groups'),
3410                                        'data'  => $cal_grps
3411                                );
3412                        }
3413
3414                        $participants = array();
3415                        foreach($event['participants'] as $user => $short_status)
3416                        {
3417                                if($GLOBALS['phpgw']->accounts->exists($user))
3418                                {
3419                                        $participants[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user).' ('.$this->get_long_status($short_status).')';
3420                                }
3421                        }
3422                        $var['participants'] = Array(
3423                                'field' => lang('Participants'),
3424                                'data'  => $participants
3425                        );
3426
3427                        // Repeated Events
3428                        if($event['recur_type'] != MCAL_RECUR_NONE)
3429                        {
3430                                $str = lang($this->rpt_type[$event['recur_type']]);
3431
3432                                $str_extra = array();
3433                                if ($event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['year'] != 0)
3434                                {
3435                                        $recur_end = $this->maketime($event['recur_enddate']);
3436                                        if($recur_end != 0)
3437                                        {
3438                                                $recur_end -= $GLOBALS['phpgw']->datetime->tz_offset;
3439                                                $str_extra[] = lang('ends').': '.lang($GLOBALS['phpgw']->common->show_date($recur_end,'l')).', '.$this->long_date($recur_end).' ';
3440                                        }
3441                                }
3442                                // only weekly uses the recur-data (days) !!!
3443                                if($event['recur_type'] == MCAL_RECUR_WEEKLY)
3444                                {
3445                                        $repeat_days = array();
3446                                        foreach ($this->rpt_day as $mcal_mask => $dayname)
3447                                        {
3448                                                if ($event['recur_data'] & $mcal_mask)
3449                                                {
3450                                                        $repeat_days[] = lang($dayname);
3451                                                }
3452                                        }
3453                                        if(count($repeat_days))
3454                                        {
3455                                                $str_extra[] = lang('days repeated').': '.implode(', ',$repeat_days);
3456                                        }
3457                                }
3458                                if($event['recur_interval'] != 0)
3459                                {
3460                                        $str_extra[] = lang('Interval').': '.$event['recur_interval'];
3461                                }
3462
3463                                if(count($str_extra))
3464                                {
3465                                        $str .= ' ('.implode(', ',$str_extra).')';
3466                                }
3467
3468                                $var['recure_type'] = Array(
3469                                        'field' => lang('Repetition'),
3470                                        'data'  => $str,
3471                                );
3472                        }
3473
3474                        if (!isset($this->fields))
3475                        {
3476                                $this->custom_fields = CreateObject('calendar.bocustom_fields');
3477                                $this->fields = &$this->custom_fields->fields;
3478                                $this->stock_fields = &$this->custom_fields->stock_fields;
3479                        }
3480                        foreach($this->fields as $field => $data)
3481                        {
3482                                if (!$data['disabled'])
3483                                {
3484                                        if (isset($var[$field]))
3485                                        {
3486                                                $sorted[$field] = $var[$field];
3487                                        }
3488                                        elseif (!isset($this->stock_fields[$field]) && strlen($event[$field]))  // Custom field
3489                                        {
3490                                                $lang = lang($name = substr($field,1));
3491                                                $sorted[$field] = array(
3492                                                        'field' => $lang == $name.'*' ? $name : $lang,
3493                                                        'data'  => $event[$field]
3494                                                );
3495                                        }
3496                                }
3497                                unset($var[$field]);
3498                        }
3499                        foreach($var as $name => $v)
3500                        {
3501                                $sorted[$name] = $v;
3502
3503                        }
3504                        return $sorted;
3505                }
3506
3507                /*!
3508                @function check_set_default_prefs
3509                @abstract sets the default prefs, if they are not already set (on a per pref. basis)
3510                @note It sets a flag in the app-session-data to be called only once per session
3511                */
3512                function check_set_default_prefs()
3513                {
3514                        if (($set = $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar')))
3515                        {
3516                                return;
3517                        }
3518                        $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar','set');
3519
3520                        //$default_prefs = $GLOBALS['phpgw']->preferences->default['calendar']; jakjr
3521
3522                        $subject = lang('Calendar Event') . ' - $$action$$: $$startdate$$ $$title$$'."\n";
3523                        $defaults = array(
3524                                'defaultcalendar' => 'week',
3525                                'mainscreen_showevents' => '0',
3526                                'summary'         => 'no',
3527                                'receive_updates' => 'no',
3528                                'update_format'   => 'extended',        // leave it to extended for now, as iCal kills the message-body
3529                                'notifyAdded'     => $subject . lang ('You have a meeting scheduled for %1','$$startdate$$'),
3530                                'notifyCanceled'  => $subject . lang ('Your meeting scheduled for %1 has been canceled','$$startdate$$'),
3531                                'notifyModified'  => $subject . lang ('Your meeting that had been scheduled for %1 has been rescheduled to %2','$$olddate$$','$$startdate$$'),
3532                                'notifyResponse'  => $subject . lang ('On %1 %2 %3 your meeting request for %4','$$date$$','$$fullname$$','$$action$$','$$startdate$$'),
3533                                'notifyAlarm'     => lang('Alarm for %1 at %2 in %3','$$title$$','$$startdate$$','$$location$$')."\n".lang ('Here is your requested alarm.'),
3534                                'show_rejected'   => '0',
3535                                'display_status'  => '1',
3536                                'weekdaystarts'   => 'Monday',
3537                                'workdaystarts'   => '9',
3538                                'workdayends'     => '17',
3539                                'interval'        => '30',
3540                                'defaultlength'   => '60',
3541                                'planner_start_with_group' => $GLOBALS['phpgw']->accounts->name2id('Default'),
3542                                'planner_intervals_per_day'=> '4',
3543                                'defaultfilter'   => 'all',
3544                                'default_private' => '0',
3545                                'display_minicals'=> '1',
3546                                'print_black_white'=>'0'
3547                        );
3548                        foreach($defaults as $var => $default)
3549                        {
3550                                if (!isset($default_prefs[$var]) || $default_prefs[$var] == '')
3551                                {
3552                                        $GLOBALS['phpgw']->preferences->add('calendar',$var,$default,'default');
3553                                        $need_save = True;
3554                                }
3555                        }
3556                        if ($need_save)
3557                        {
3558                                $prefs = $GLOBALS['phpgw']->preferences->save_repository(False,'default');
3559                                $this->prefs['calendar'] = $prefs['calendar'];
3560                        }
3561                        if ($this->prefs['calendar']['send_updates'] && !isset($this->prefs['calendar']['receive_updates']))
3562                        {
3563                                $this->prefs['calendar']['receive_updates'] = $this->prefs['calendar']['send_updates'];
3564                                $GLOBALS['phpgw']->preferences->add('calendar','receive_updates',$this->prefs['calendar']['send_updates']);
3565                                $GLOBALS['phpgw']->preferences->delete('calendar','send_updates');
3566                                $prefs = $GLOBALS['phpgw']->preferences->save_repository();
3567                        }
3568                }
3569
3570                // return array with all infolog categories (for xmlrpc)
3571                function categories($complete = False)
3572                {
3573                        return $GLOBALS['server']->categories($complete);
3574                }
3575        }
3576?>
Note: See TracBrowser for help on using the repository browser.