Sharedwww / cgi-bin / openwebmail / openwebmail-cal.plOpen in CoCalc
Author: William A. Stein
1
#!/usr/bin/perl
2
#
3
# openwebmail-cal.pl - calendar program
4
#
5
# 2003/12/15 ateslik.AT.users.sourceforge.net
6
# DHTML popup calendar support
7
# 2003/09/02 ateslik.AT.users.sourceforge.net
8
# rewrite the calendar item add/update stuff
9
# 2003/03/29 [email protected]
10
# easter day support
11
# 2003/02/17 ateslik.AT.users.sourceforge.net
12
# rewrite the dayview display
13
# 2002/07/05 tung.AT.turtle.ee.ncku.edu.tw
14
# modified from WebCal version 1.12.
15
#
16
# WebCal is available at http://bulldog.tzo.org/webcal/webcal.html/
17
# and is copyrighted by 2002, Michael Arndt
18
#
19
20
use vars qw($SCRIPT_DIR);
21
if ( $0 =~ m!^(.*?)/[\w\d\-\.]+\.pl! ) { $SCRIPT_DIR=$1 }
22
if ($SCRIPT_DIR eq '' && open(F, '/etc/openwebmail/openwebmail_path.conf')) {
23
$_=<F>; close(F); if ( $_=~/^([^\s]*)/) { $SCRIPT_DIR=$1 }
24
}
25
if ($SCRIPT_DIR eq '') { print "Content-type: text/html\n\nSCRIPT_DIR not set in /etc/openwebmail/openwebmail_path.conf !\n"; exit 0; }
26
push (@INC, $SCRIPT_DIR);
27
28
foreach (qw(ENV BASH_ENV CDPATH IFS TERM)) {delete $ENV{$_}}; $ENV{PATH}='/bin:/usr/bin'; # secure ENV
29
umask(0002); # make sure the openwebmail group can write
30
31
use strict;
32
use Fcntl qw(:DEFAULT :flock);
33
use CGI qw(-private_tempfiles :standard);
34
use CGI::Carp qw(fatalsToBrowser carpout);
35
36
require "modules/dbm.pl";
37
require "modules/suid.pl";
38
require "modules/filelock.pl";
39
require "modules/tool.pl";
40
require "modules/datetime.pl";
41
require "modules/lang.pl";
42
require "auth/auth.pl";
43
require "quota/quota.pl";
44
require "shares/ow-shared.pl";
45
require "shares/lunar.pl";
46
require "shares/iconv-chinese.pl";
47
require "shares/calbook.pl";
48
49
# common globals
50
use vars qw(%config %config_raw);
51
use vars qw($thissession);
52
use vars qw($domain $user $userrealname $uuid $ugid $homedir);
53
use vars qw(%prefs %style %icontext);
54
55
# extern vars
56
use vars qw(%lang_folders %lang_text %lang_err); # defined in lang/xy
57
use vars qw(%lang_calendar %lang_month %lang_wday_abbrev %lang_wday %lang_order); # defined in lang/xy
58
59
# local globals
60
use vars qw($folder $messageid);
61
use vars qw($escapedfolder $escapedmessageid);
62
use vars qw($miscbuttonsstr);
63
use vars qw(@slottime);
64
65
########## MAIN ##################################################
66
openwebmail_requestbegin();
67
$SIG{PIPE}=\&openwebmail_exit; # for user stop
68
$SIG{TERM}=\&openwebmail_exit; # for user stop
69
70
userenv_init();
71
72
if (!$config{'enable_calendar'}) {
73
openwebmailerror(__FILE__, __LINE__, "$lang_text{'calendar'} $lang_err{'access_denied'}");
74
}
75
76
$folder = param('folder') || 'INBOX';
77
$messageid = param('message_id') ||'';
78
79
$escapedfolder = ow::tool::escapeURL($folder);
80
$escapedmessageid = ow::tool::escapeURL($messageid);
81
82
# init global @slottime
83
@slottime=();
84
for my $h (0..23) {
85
for (my $m=0; $m<60 ; $m=$m+$prefs{'calendar_interval'}) {
86
push(@slottime, sprintf("%02d%02d", $h, $m));
87
}
88
}
89
push(@slottime, "2400");
90
91
$miscbuttonsstr='';
92
if ($config{'enable_webmail'}) {
93
if ($messageid eq "") {
94
$miscbuttonsstr .= iconlink("owm.gif", "$lang_text{'backto'} ".($lang_folders{$folder}||$folder),
95
qq|accesskey="M" href="$config{'ow_cgiurl'}/openwebmail-main.pl?action=listmessages&amp;sessionid=$thissession&amp;folder=$escapedfolder"|);
96
} else {
97
$miscbuttonsstr .= iconlink("owm.gif", "$lang_text{'backto'} ".($lang_folders{$folder}||$folder),
98
qq|accesskey="M" href="$config{'ow_cgiurl'}/openwebmail-read.pl?action=readmessage&amp;sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid"|);
99
}
100
}
101
if ($config{'enable_webdisk'}) {
102
$miscbuttonsstr .= iconlink("webdisk.gif", $lang_text{'webdisk'}, qq|accesskey="E" href="$config{'ow_cgiurl'}/openwebmail-webdisk.pl?action=showdir&amp;sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid"|);
103
}
104
if ( $config{'enable_sshterm'}) {
105
if ( -r "$config{'ow_htmldir'}/applet/mindterm2/mindterm.jar" ) {
106
$miscbuttonsstr .= iconlink("sshterm.gif" ,"$lang_text{'sshterm'} ", qq|accesskey="T" href="#" onClick="window.open('$config{ow_htmlurl}/applet/mindterm2/ssh2.html', '_applet', 'width=400,height=100,top=2000,left=2000,resizable=no,menubar=no,scrollbars=no');"|);
107
} elsif ( -r "$config{'ow_htmldir'}/applet/mindterm/mindtermfull.jar" ) {
108
$miscbuttonsstr .= iconlink("sshterm.gif" ,"$lang_text{'sshterm'} ", qq|accesskey="T" href="#" onClick="window.open('$config{ow_htmlurl}/applet/mindterm/ssh.html', '_applet', 'width=400,height=100,top=2000,left=2000,resizable=no,menubar=no,scrollbars=no');"|);
109
}
110
}
111
if ( $config{'enable_preference'}) {
112
$miscbuttonsstr .= iconlink("prefs.gif", $lang_text{'userprefs'}, qq|accesskey="O" href="$config{'ow_cgiurl'}/openwebmail-prefs.pl?action=editprefs&amp;sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid&amp;prefs_caller=cal"|);
113
}
114
$miscbuttonsstr .= iconlink("logout.gif", "$lang_text{'logout'} $prefs{'email'}", qq|accesskey="X" href="$config{'ow_cgiurl'}/openwebmail-main.pl?sessionid=$thissession&amp;action=logout"|);
115
116
my $action = param('action')||'';
117
# event background colors
118
my %eventcolors=( '1a'=>'b0b0e0', '1b'=>'b0e0b0', '1c'=>'b0e0e0',
119
'1d'=>'e0b0b0', '1e'=>'e0b0e0', '1f'=>'e0e0b0',
120
'2a'=>'9090f8', '2b'=>'90f890', '2c'=>'90f8f8',
121
'2d'=>'f89090', '2e'=>'f890f8', '2f'=>'f8f890');
122
123
my $year=param('year')||'';
124
my $month=param('month')||'';
125
my $day=param('day')||'';
126
if (defined(param('daybutton'))) {
127
$day=param('daybutton'); $day=~s/\s//g;
128
}
129
130
my $index=param('index')||'';
131
my $string=param('string')||'';
132
my $starthour=param('starthour')||0;
133
my $startmin=param('startmin')||0;
134
my $startampm=param('startampm')||'am';
135
my $endhour=param('endhour')||0;
136
my $endmin=param('endmin')||0;
137
my $endampm=param('endampm')||'am';
138
my $link=param('link')||'';
139
my $email=param('email')||'';
140
my $eventcolor=param('eventcolor')||'none';
141
my $dayfreq=param('dayfreq')||'thisdayonly';
142
my $thisandnextndays=param('thisandnextndays')||0;
143
my $ndays=param('ndays')||0;
144
my $monthfreq=param('monthfreq')||0;
145
my $everyyear=param('everyyear')||0;
146
147
if ($action eq "calyear") {
148
yearview($year);
149
} elsif ($action eq "calmonth") {
150
monthview($year, $month);
151
} elsif ($action eq "calweek") {
152
weekview($year, $month, $day);
153
} elsif ($action eq "calday") {
154
dayview($year, $month, $day);
155
} elsif ($action eq "callist") {
156
listview($year);
157
} elsif ($action eq "caledit") {
158
edit_item($year, $month, $day, $index);
159
} elsif ($action eq "caladd") {
160
add_item($year, $month, $day,
161
$string,
162
$starthour, $startmin, $startampm,
163
$endhour, $endmin, $endampm,
164
$dayfreq,
165
$thisandnextndays, $ndays, $monthfreq, $everyyear,
166
$link, $email, $eventcolor);
167
dayview($year, $month, $day);
168
} elsif ($action eq "caldel") {
169
del_item($index);
170
if (defined(param('callist'))) {
171
listview($year);
172
} else {
173
dayview($year, $month, $day);
174
}
175
} elsif ($action eq "calupdate") {
176
update_item($index,
177
$year, $month, $day,
178
$string,
179
$starthour, $startmin, $startampm,
180
$endhour, $endmin, $endampm,
181
$dayfreq,
182
$thisandnextndays, $ndays, $monthfreq, $everyyear,
183
$link, $email, $eventcolor);
184
185
if (defined(param('callist'))) {
186
listview($year);
187
} else {
188
dayview($year, $month, $day);
189
}
190
} else {
191
openwebmailerror(__FILE__, __LINE__, "Action $lang_err{'has_illegal_chars'}");
192
}
193
194
openwebmail_requestend();
195
########## END MAIN ##############################################
196
197
########## YEARVIEW ##############################################
198
sub yearview {
199
my $year=$_[0];
200
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
201
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
202
203
my $localtime=ow::datetime::time_gm2local(time(), $prefs{'timeoffset'}, $prefs{'daylightsaving'});
204
my ($current_year, $current_month, $current_day)=(ow::datetime::seconds2array($localtime))[5,4,3];
205
$current_year+=1900; $current_month++;
206
207
$year = $current_year if (!$year);
208
$year=2037 if ($year>2037); $year=1970 if ($year<1970);
209
210
my ($html, $temphtml);
211
$html = applystyle(readtemplate("yearview.template"));
212
213
$temphtml = startform(-name=>'dateselform',
214
-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
215
ow::tool::hiddens(action=>'calyear',
216
sessionid=>$thissession,
217
folder=>$folder,
218
message_id=>$messageid);
219
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/g;
220
221
$html =~ s/\@\@\@DATESELMENU\@\@\@/$lang_text{'calfmt_year'}/g;
222
223
$temphtml = popup_menu(-name=>'year',
224
-values=>[1970..2037],
225
-default=>$year,
226
-onChange=>"submit()",
227
-accesskey=>'G',
228
-override=>'1');
229
$html =~ s/\@\@\@YEAR\@\@\@/ $temphtml /;
230
231
$temphtml = end_form();
232
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
233
234
$temphtml = formatted_date($year);
235
$html =~ s/\@\@\@CALTITLE\@\@\@/$temphtml/g;
236
237
my $cal_url=qq|$config{'ow_cgiurl'}/openwebmail-cal.pl?sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid|;
238
239
$temphtml = calbuttonsstr($cal_url, $year, $current_month, $current_day);
240
if ($year != $current_year) {
241
$temphtml .= iconlink("refresh.gif", "$lang_text{'backto'} ".formatted_date($current_year), qq|accesskey="R" href="$cal_url&amp;action=calyear&amp;year=$current_year"|);
242
}
243
$temphtml .= "&nbsp;\n$miscbuttonsstr";
244
$html =~ s/\@\@\@MENUBARLINKS\@\@\@/$temphtml/g;
245
246
my $prev_year = $year - 1;
247
my $gif="left.gif"; $gif="right.gif" if ($ow::lang::RTL{$prefs{'language'}});
248
$temphtml=iconlink($gif, formatted_date($prev_year), qq|accesskey="U" href="$cal_url&amp;action=calyear&amp;year=$prev_year"|). qq| \n|;
249
$html =~ s/\@\@\@PREV_LINK\@\@\@/$temphtml/g;
250
251
my $next_year = $year + 1;
252
$gif="right.gif"; $gif="left.gif" if ($ow::lang::RTL{$prefs{'language'}});
253
$temphtml=iconlink($gif, formatted_date($next_year), qq|accesskey="D" href="$cal_url&amp;action=calyear&amp;year=$next_year"|). qq| \n|;
254
$html =~ s/\@\@\@NEXT_LINK\@\@\@/$temphtml/g;
255
256
my (%items, %indexes);
257
my $calbookfile=dotpath('calendar.book');
258
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
259
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
260
}
261
if ($prefs{'calendar_reminderforglobal'}) {
262
readcalbook("$config{'global_calendarbook'}", \%items, \%indexes, 1E6);
263
if ($prefs{'calendar_holidaydef'} eq 'auto') {
264
readcalbook("$config{'ow_holidaysdir'}/$prefs{'language'}", \%items, \%indexes, 1E7);
265
} elsif ($prefs{'calendar_holidaydef'} ne 'none') {
266
readcalbook("$config{'ow_holidaysdir'}/$prefs{'calendar_holidaydef'}", \%items, \%indexes, 1E7);
267
}
268
}
269
270
my @accesskey=qw(0 1 2 3 4 5 6 7 8 9 0 J Q);
271
my $week=1;
272
for my $month (1..12) {
273
my @days = set_days_in_month($year, $month, $days_in_month[$month]);
274
275
my $bgcolor=$style{tablerow_light};
276
$bgcolor=$style{tablerow_dark} if ($month==$current_month && $year == $current_year);
277
my $td_bgcolorstr=qq|bgcolor=$bgcolor |;
278
if ($prefs{'uselightbar'}) {
279
$td_bgcolorstr.=qq|onMouseOver='this.style.backgroundColor=$style{tablerow_hicolor};' |.
280
qq|onMouseOut='this.style.backgroundColor=$bgcolor;' |.
281
qq|onClick="window.location.href='$cal_url&amp;action=calmonth&amp;year=$year&amp;month=$month';"|;
282
}
283
284
$temphtml = qq|<td valign=top align=center $td_bgcolorstr>\n|;
285
$temphtml .= qq|<table border="0" width="100%"><tr><td align="center">|.
286
qq|<a accesskey="$accesskey[$month]" href="$cal_url&amp;action=calmonth&amp;year=$year&amp;month=$month">|.
287
qq|<B>$lang_month{$month}</B></a>|.
288
qq|</td></tr></table>\n|;
289
$temphtml .= qq|<table border="0" cellpadding="1" cellspacing="0" width="100%">\n|;
290
$temphtml .= qq|<tr align=center><td>$lang_wday_abbrev{'week'}</td>|;
291
for (my $i=0; $i<7; $i++) {
292
$temphtml.=qq|<td align=center>|.
293
$lang_wday_abbrev{($prefs{'calendar_weekstart'}+$i)%7}.
294
qq|</td>|;
295
}
296
$temphtml .= qq|</tr>\n|;
297
298
for my $x (0..5) {
299
$temphtml .= qq|<tr align=center>|;
300
if (($days[$x][0]) || ($days[$x][6])) {
301
$day = $days[$x][0]||$days[$x][6];
302
$temphtml .= qq|<td><a href="$cal_url&amp;action=calweek&amp;year=$year&amp;month=$month&amp;day=$day">|.
303
qq|<font color=#c00000>$week</font></a></td>\n|;
304
}
305
for my $y (0..6) {
306
if ($days[$x][$y]) {
307
$day = $days[$x][$y];
308
309
my $wdaynum=($prefs{'calendar_weekstart'}+$y)%7;
310
my $dow=$ow::datetime::wday_en[$wdaynum%7];
311
my $date=sprintf("%04d%02d%02d", $year,$month,$day);
312
my $date2=sprintf("%04d,%02d,%02d,%s", $year,$month,$day,$dow);
313
314
my @indexlist=();
315
foreach ($date, '*') {
316
next if (!defined($indexes{$_}));
317
foreach my $index (@{$indexes{$_}}) {
318
if ($date =~/$items{$index}{'idate'}/ ||
319
$date2=~/$items{$index}{'idate'}/ ||
320
ow::datetime::easter_match($year,$month,$day,$items{$index}{'idate'}) ) {
321
push(@indexlist, $index);
322
}
323
}
324
}
325
@indexlist=sort { $items{$a}{'starthourmin'}<=>$items{$b}{'starthourmin'} ||
326
$items{$a}{'endhourmin'}<=>$items{$b}{'endhourmin'} ||
327
$b<=>$a } @indexlist;
328
329
my $eventstr='';
330
for my $index (@indexlist) {
331
$eventstr.="$items{$index}{'string'} ";
332
}
333
if ($eventstr ne '') {
334
if ($eventstr!~/"/) {
335
$eventstr=qq|title="$eventstr"|;
336
} else {
337
$eventstr=qq|title='$eventstr'|;
338
}
339
}
340
341
if ($day==$current_day && $month==$current_month && $year==$current_year) {
342
$temphtml .= qq|<td bgcolor=$style{'tablerow_hicolor'}>|;
343
} else {
344
$temphtml .= qq|<td>|;
345
}
346
$temphtml .= qq|<a href="$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day" $eventstr>|;
347
if ($eventstr ne '') {
348
$temphtml .= qq|<b>$days[$x][$y]</b>|;
349
} else {
350
$temphtml .= qq|$days[$x][$y]|;
351
}
352
$temphtml .= qq|</a></td>\n|;
353
354
$week++ if ($y==6 && $week<53);
355
} else {
356
$temphtml .= qq|<td>&nbsp;</td>|;
357
}
358
}
359
$temphtml .= qq|</tr>\n|;
360
}
361
$temphtml .= qq|</table></td>\n|;
362
$html =~ s/\@\@\@MONTH$month\@\@\@/$temphtml/;
363
}
364
365
httpprint([],
366
[htmlheader(), htmlplugin($config{'header_pluginfile'}),
367
$html,
368
htmlplugin($config{'footer_pluginfile'}), htmlfooter(2)] );
369
}
370
########## END YEARVIEW ##########################################
371
372
########## MONTHVIEW #############################################
373
sub monthview {
374
my ($year, $month)=@_;
375
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
376
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
377
378
my $localtime=ow::datetime::time_gm2local(time(), $prefs{'timeoffset'}, $prefs{'daylightsaving'});
379
my ($current_year, $current_month, $current_day)=(ow::datetime::seconds2array($localtime))[5,4,3];
380
$current_year+=1900; $current_month++;
381
382
$year = $current_year if (!$year);
383
$month = $current_month if (!$month);
384
$year=2037 if ($year>2037); $year=1970 if ($year<1970);
385
$month=12 if ($month>12); $month=1 if ($month<1);
386
387
my ($html, $temphtml);
388
$html = applystyle(readtemplate("monthview.template"));
389
390
$temphtml = startform(-name=>'dateselform',
391
-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
392
ow::tool::hiddens(action=>'calmonth',
393
sessionid=>$thissession,
394
folder=>$folder,
395
message_id=>$messageid);
396
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/g;
397
398
$html =~ s/\@\@\@DATESELMENU\@\@\@/$lang_text{'calfmt_yearmonth'}/g;
399
400
$temphtml = popup_menu(-name=>'year',
401
-values=>[1970..2037],
402
-default=>$year,
403
-onChange=>"submit()",
404
-accesskey=>'G',
405
-override=>'1');
406
$html =~ s/\@\@\@YEAR\@\@\@/ $temphtml /;
407
408
$temphtml = popup_menu(-name=>'month',
409
-values=>[1..12],
410
-labels=>\%lang_month,
411
-default=>$month,
412
-onChange=>"submit()",
413
-accesskey=>'G',
414
-override=>'1');
415
$html =~ s/\@\@\@MONTH_STR\@\@\@/ $temphtml /;
416
417
$temphtml = end_form();
418
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
419
420
$temphtml = formatted_date($year, $month);
421
$html =~ s/\@\@\@CALTITLE\@\@\@/$temphtml/g;
422
423
my $cal_url=qq|$config{'ow_cgiurl'}/openwebmail-cal.pl?sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid|;
424
425
$temphtml = calbuttonsstr($cal_url, $year, $month, $current_day);
426
if ($year!=$current_year || $month!=$current_month) {
427
$temphtml .= iconlink("refresh.gif", "$lang_text{'backto'} ".formatted_date($current_year,$current_month), qq|accesskey="R" href="$cal_url&amp;action=calmonth&amp;year=$current_year&amp;month=$current_month"|);
428
}
429
$temphtml .= "&nbsp;\n$miscbuttonsstr";
430
$html =~ s/\@\@\@MENUBARLINKS\@\@\@/$temphtml/g;
431
432
my ($prev_year, $prev_month)= ($year, $month-1);
433
if ($month == 1) {
434
($prev_year, $prev_month) = ($year-1, 12);
435
}
436
my $gif="left.gif"; $gif="right.gif" if ($ow::lang::RTL{$prefs{'language'}});
437
$temphtml=iconlink($gif, formatted_date($prev_year,$prev_month), qq|accesskey="U" href="$cal_url&amp;action=calmonth&amp;year=$prev_year&amp;month=$prev_month"|). qq| \n|;
438
$html =~ s/\@\@\@PREV_LINK\@\@\@/$temphtml/g;
439
440
my ($next_year, $next_month)= ($year, $month+1);
441
if ($month == 12) {
442
($next_year, $next_month) = ($year+1, 1);
443
}
444
$gif="right.gif"; $gif="left.gif" if ($ow::lang::RTL{$prefs{'language'}});
445
$temphtml=iconlink($gif, formatted_date($next_year,$next_month), qq|accesskey="D" href="$cal_url&amp;action=calmonth&amp;year=$next_year&amp;month=$next_month"|). qq| \n|;
446
$html =~ s/\@\@\@NEXT_LINK\@\@\@/$temphtml/g;
447
448
for (my $i=0; $i<7; $i++) {
449
my $n=($prefs{'calendar_weekstart'}+$i)%7;
450
if ($n==0) { # sunday
451
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!<font color=#cc0000>$lang_wday{$n}</font>!;
452
} elsif ($n==6) { # saturday
453
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!<font color=#00aa00>$lang_wday{$n}</font>!;
454
} else {
455
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!$lang_wday{$n}!;
456
}
457
}
458
459
my (%items, %indexes);
460
my $calbookfile=dotpath('calendar.book');
461
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
462
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
463
}
464
if ($prefs{'calendar_reminderforglobal'}) {
465
readcalbook("$config{'global_calendarbook'}", \%items, \%indexes, 1E6);
466
if ($prefs{'calendar_holidaydef'} eq 'auto') {
467
readcalbook("$config{'ow_holidaysdir'}/$prefs{'language'}", \%items, \%indexes, 1E7);
468
} elsif ($prefs{'calendar_holidaydef'} ne 'none') {
469
readcalbook("$config{'ow_holidaysdir'}/$prefs{'calendar_holidaydef'}", \%items, \%indexes, 1E7);
470
}
471
}
472
473
$temphtml = start_form(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
474
ow::tool::hiddens(sessionid=>$thissession,
475
folder=>$folder,
476
message_id=>$messageid,
477
action=>'calday',
478
year=>$year,
479
month=>$month);
480
$html =~ s/\@\@\@STARTDAYFORM\@\@\@/$temphtml/;
481
482
my @days = set_days_in_month($year, $month, $days_in_month[$month]);
483
for my $x ( 0..5 ) {
484
for my $y ( 0..6 ) {
485
my $day = $days[$x][$y];
486
487
my ($td_bgcolorstr, $bgcolor);
488
if ($year==$current_year && $month==$current_month && $day==$current_day) {
489
$bgcolor=$style{tablerow_dark};
490
} elsif ($days[$x][$y]) {
491
$bgcolor=$style{tablerow_light};
492
} # else cell is not unused, bgcolor is not required
493
if ($bgcolor ne '') {
494
$td_bgcolorstr=qq|bgcolor=$bgcolor |;
495
if ($prefs{'uselightbar'}) {
496
$td_bgcolorstr.=qq|onMouseOver='this.style.backgroundColor=$style{tablerow_hicolor};' |.
497
qq|onMouseOut='this.style.backgroundColor=$bgcolor;' |.
498
qq|onClick="window.location.href='$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day';"|;
499
}
500
}
501
502
$temphtml = qq|<td $td_bgcolorstr valign=top>|.
503
qq|<table width="100%" cellpadding="0" cellspacing="0">\n|;
504
505
if ($days[$x][$y] =~ /\d+/) {
506
my $t=ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
507
my $dow=$ow::datetime::wday_en[(ow::datetime::seconds2array($t))[6]];
508
my $date=sprintf("%04d%02d%02d", $year, $month, $day);
509
my $date2=sprintf("%04d,%02d,%02d,%s", $year,$month,$day,$dow);
510
my $i=0;
511
512
$temphtml .= qq|<tr><td align="right">|;
513
if ($prefs{'charset'} eq "big5" || $prefs{'charset'} eq "gb2312") {
514
$temphtml.=lunar_str($year, $month, $day, $prefs{'charset'});
515
}
516
my $daystr=$days[$x][$y]; $daystr=" ".$daystr if (length($daystr)<2);
517
$temphtml .= submit(-name=>'daybutton',
518
-value=>$daystr,
519
-override=>'1').
520
qq|</td></tr>|;
521
522
my @indexlist=();
523
foreach ($date, '*') {
524
next if (!defined($indexes{$_}));
525
foreach my $index (@{$indexes{$_}}) {
526
if ($date =~/$items{$index}{'idate'}/ ||
527
$date2=~/$items{$index}{'idate'}/ ||
528
ow::datetime::easter_match($year,$month,$day,$items{$index}{'idate'}) ) {
529
push(@indexlist, $index);
530
}
531
}
532
}
533
@indexlist=sort { $items{$a}{'starthourmin'}<=>$items{$b}{'starthourmin'} ||
534
$items{$a}{'endhourmin'}<=>$items{$b}{'endhourmin'} ||
535
$b<=>$a } @indexlist;
536
537
$temphtml .= qq|<tr><td>|;
538
for my $index (@indexlist) {
539
if ($i<$prefs{'calendar_monthviewnumitems'}) {
540
$temphtml .= month_week_item($items{$index}, qq|$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day|, ($index>=1E6))
541
}
542
$i++;
543
}
544
if ($i>$prefs{'calendar_monthviewnumitems'}) {
545
$temphtml .= qq|<br><br><a href="$cal_url&amp;|.
546
qq|action=calday&amp;year=$year&amp;month=$month&amp;day=$day">|.
547
qq|$lang_text{'moreitems'}</a>\n|;
548
}
549
$temphtml .= qq|&nbsp;<br>\n| if ($i==0);
550
$temphtml .= qq|</td></tr></table></td>\n|;
551
552
} else {
553
$temphtml .= qq|<tr><td>$days[$x][$y]</td></tr>|.
554
qq|<tr><td></td></tr></table></td>\n|;
555
}
556
557
$html =~ s/\@\@\@DAY$x$y\@\@\@/$temphtml/;
558
}
559
}
560
561
httpprint([],
562
[htmlheader(), htmlplugin($config{'header_pluginfile'}),
563
$html,
564
htmlplugin($config{'footer_pluginfile'}), htmlfooter(2)] );
565
}
566
########## END MONTHVIEW #########################################
567
568
########## WEEKVIEW ##############################################
569
sub weekview {
570
my ($year, $month, $day)=@_;
571
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
572
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
573
574
my $localtime=ow::datetime::time_gm2local(time(), $prefs{'timeoffset'}, $prefs{'daylightsaving'});
575
my ($current_year, $current_month, $current_day)=(ow::datetime::seconds2array($localtime))[5,4,3];
576
$current_year+=1900; $current_month++;
577
578
$year = $current_year if (!$year);
579
$month = $current_month if (!$month);
580
$day = $current_day if (!$day);
581
$year=2037 if ($year>2037); $year=1970 if ($year<1970);
582
$month=12 if ($month>12); $month=1 if ($month<1);
583
$day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
584
585
my ($html, $temphtml);
586
$html = applystyle(readtemplate("weekview.template").
587
readtemplate("calpopup.js") );
588
589
$temphtml = startform(-name=>'dateselform',
590
-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
591
ow::tool::hiddens(action=>'calweek',
592
sessionid=>$thissession,
593
folder=>$folder,
594
message_id=>$messageid);
595
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/g;
596
597
$temphtml = iconlink("cal-popup.gif", $lang_text{'calendar'}, qq|href="#" onClick="calPopup(this,'mypopupCal',-175,15,'dateselform','submit_changed_dateselform');"|);
598
$temphtml .= qq|&nbsp;$lang_text{'calfmt_yearmonthday'}|;
599
$html =~ s/\@\@\@DATESELMENU\@\@\@/$temphtml/g;
600
601
$temphtml = popup_menu(-name=>'year',
602
-values=>[1970..2037],
603
-default=>$year,
604
-onChange=>"submit()",
605
-accesskey=>'G',
606
-override=>'1');
607
$html =~ s/\@\@\@YEAR\@\@\@/ $temphtml /;
608
609
$temphtml = popup_menu(-name=>'month',
610
-values=>[1..12],
611
-labels=>\%lang_month,
612
-default=>$month,
613
-onChange=>"submit()",
614
-accesskey=>'G',
615
-override=>'1');
616
$html =~ s/\@\@\@MONTH_STR\@\@\@/ $temphtml /;
617
618
$temphtml = popup_menu(-name=>'day',
619
-values=>[1..$days_in_month[$month]],
620
-default=>$day,
621
-onChange=>"submit()",
622
-accesskey=>'G',
623
-override=>'1');
624
$html =~ s/\@\@\@DAY\@\@\@/ $temphtml /;
625
626
# replace @@@ labels with $lang vars
627
$temphtml=qq|'$lang_wday{0}','$lang_wday{1}','$lang_wday{2}','$lang_wday{3}','$lang_wday{4}','$lang_wday{5}','$lang_wday{6}'|;
628
$html =~ s/\@\@\@WDAY_ARRAY\@\@\@/$temphtml/;
629
$temphtml=qq|'$lang_order{1}','$lang_order{2}','$lang_order{3}','$lang_order{4}','$lang_order{5}'|;
630
$html =~ s/\@\@\@WORDER_ARRAY\@\@\@/$temphtml/;
631
$temphtml=qq|'$lang_wday_abbrev{0}','$lang_wday_abbrev{1}','$lang_wday_abbrev{2}','$lang_wday_abbrev{3}','$lang_wday_abbrev{4}','$lang_wday_abbrev{5}','$lang_wday_abbrev{6}'|;
632
$html =~ s/\@\@\@WDAYABBREV_ARRAY\@\@\@/$temphtml/;
633
$temphtml=qq|'$lang_month{1}','$lang_month{2}','$lang_month{3}','$lang_month{4}','$lang_month{5}','$lang_month{6}','$lang_month{7}','$lang_month{8}','$lang_month{9}','$lang_month{10}','$lang_month{11}','$lang_month{12}'|;
634
$html =~ s/\@\@\@WMONTH_ARRAY\@\@\@/$temphtml/;
635
$html =~ s/\@\@\@WSTART\@\@\@/$prefs{'calendar_weekstart'}/g;
636
$html =~ s/\@\@\@TODAY\@\@\@/$lang_text{'today'}/g;
637
638
$temphtml = end_form();
639
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
640
641
$temphtml = formatted_date($year, $month, $day);
642
$html =~ s/\@\@\@CALTITLE\@\@\@/$temphtml/g;
643
644
my $cal_url=qq|$config{'ow_cgiurl'}/openwebmail-cal.pl?sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid|;
645
646
$temphtml = calbuttonsstr($cal_url, $year, $month, $day);
647
if ($year!=$current_year || $month!=$current_month || $day!=$current_day) {
648
$temphtml .= iconlink("refresh.gif", "$lang_text{'backto'} $lang_calendar{'weekview'} ".formatted_date($current_year,$current_month,$current_day), qq|href="$cal_url&amp;action=calweek&amp;year=$current_year&amp;month=$current_month&amp;day=$current_day"|). qq| \n|;
649
}
650
$temphtml .= "&nbsp;\n$miscbuttonsstr";
651
$html =~ s/\@\@\@MENUBARLINKS\@\@\@/$temphtml/g;
652
653
my $time = ow::datetime::array2seconds(0,0,12, $day,$month-1,$year-1900);
654
655
my ($prev_year, $prev_month, $prev_day)=(ow::datetime::seconds2array($time-86400*7))[5,4,3];
656
$prev_year+=1900; $prev_month++;
657
my $gif="left.gif"; $gif="right.gif" if ($ow::lang::RTL{$prefs{'language'}});
658
$temphtml=iconlink($gif, "$lang_calendar{'weekview'} ".formatted_date($prev_year,$prev_month,$prev_day), qq|href="$cal_url&amp;action=calweek&amp;year=$prev_year&amp;month=$prev_month&amp;day=$prev_day"|). qq| \n|;
659
$html =~ s/\@\@\@PREV_LINK\@\@\@/$temphtml/g;
660
661
my ($next_year, $next_month, $next_day)=(ow::datetime::seconds2array($time+86400*7))[5,4,3];
662
$next_year+=1900; $next_month++;
663
$gif="right.gif"; $gif="left.gif" if ($ow::lang::RTL{$prefs{'language'}});
664
$temphtml=iconlink($gif, "$lang_calendar{'weekview'} ".formatted_date($next_year,$next_month,$next_day), qq|href="$cal_url&amp;action=calweek&amp;year=$next_year&amp;month=$next_month&amp;day=$next_day"|). qq| \n|;
665
$html =~ s/\@\@\@NEXT_LINK\@\@\@/$temphtml/g;
666
667
my $wdaynum = (ow::datetime::seconds2array($time))[6];
668
my $start_time = $time - 86400 * (($wdaynum+7-$prefs{'calendar_weekstart'})%7);
669
for (my $i=0; $i<7; $i++) {
670
my $n=($prefs{'calendar_weekstart'}+$i)%7;
671
if ($n==0) { # sunday
672
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!<font color=#cc0000>$lang_wday{$n}</font>!;
673
} elsif ($n==6) { # saturday
674
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!<font color=#00aa00>$lang_wday{$n}</font>!;
675
} else {
676
$html =~ s!\@\@\@WEEKDAY$i\@\@\@!$lang_wday{$n}!;
677
}
678
}
679
my $wdaynum = (ow::datetime::seconds2array($time))[6];
680
my $start_time = $time - 86400 * (($wdaynum+7-$prefs{'calendar_weekstart'})%7);
681
682
my (%items, %indexes);
683
my $calbookfile=dotpath('calendar.book');
684
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
685
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
686
}
687
if ($prefs{'calendar_reminderforglobal'}) {
688
readcalbook("$config{'global_calendarbook'}", \%items, \%indexes, 1E6);
689
if ($prefs{'calendar_holidaydef'} eq 'auto') {
690
readcalbook("$config{'ow_holidaysdir'}/$prefs{'language'}", \%items, \%indexes, 1E7);
691
} elsif ($prefs{'calendar_holidaydef'} ne 'none') {
692
readcalbook("$config{'ow_holidaysdir'}/$prefs{'calendar_holidaydef'}", \%items, \%indexes, 1E7);
693
}
694
}
695
696
for my $x (0..6) {
697
($year, $month, $day)=(ow::datetime::seconds2array($start_time+$x*86400))[5,4,3];
698
$year+=1900; $month++;
699
700
my $bgcolor=$style{tablerow_light};
701
$bgcolor=$style{tablerow_dark} if ($month==$current_month && $year == $current_year);
702
my $td_bgcolorstr=qq|bgcolor=$bgcolor |;
703
if ($prefs{'uselightbar'}) {
704
$td_bgcolorstr.=qq|onMouseOver='this.style.backgroundColor=$style{tablerow_hicolor};' |.
705
qq|onMouseOut='this.style.backgroundColor=$bgcolor;' |.
706
qq|onClick="window.location.href='$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day';"|;
707
}
708
709
$temphtml = qq|<td $td_bgcolorstr valign=top>|.
710
qq|<table width="100%" cellpadding="0" cellspacing="0">\n|;
711
712
my $daystr=$day; $daystr=" ".$daystr if (length($daystr)<2);
713
$temphtml .= start_form(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
714
-name=> "day$day").
715
ow::tool::hiddens(sessionid=>$thissession,
716
folder=>$folder,
717
message_id=>$messageid,
718
action=>'calday',
719
year=>$year,
720
month=>$month,
721
day=>$day).
722
qq|<tr><td align="right">|.
723
lunar_str($year, $month, $day, $prefs{'charset'}).
724
submit("$daystr").
725
qq|</td></tr>|.
726
end_form();
727
728
my $t=ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
729
my $dow=$ow::datetime::wday_en[(ow::datetime::seconds2array($t))[6]];
730
my $date=sprintf("%04d%02d%02d", $year, $month, $day);
731
my $date2=sprintf("%04d,%02d,%02d,%s", $year,$month,$day,$dow);
732
my $i=0;
733
734
my @indexlist=();
735
foreach ($date, '*') {
736
next if (!defined($indexes{$_}));
737
foreach my $index (@{$indexes{$_}}) {
738
if ($date =~/$items{$index}{'idate'}/ ||
739
$date2=~/$items{$index}{'idate'}/ ||
740
ow::datetime::easter_match($year,$month,$day,$items{$index}{'idate'}) ) {
741
push(@indexlist, $index);
742
}
743
}
744
}
745
@indexlist=sort { $items{$a}{'starthourmin'}<=>$items{$b}{'starthourmin'} ||
746
$items{$a}{'endhourmin'}<=>$items{$b}{'endhourmin'} ||
747
$b<=>$a } @indexlist;
748
749
$temphtml .= qq|<tr><td valign=bottom>|;
750
for my $index (@indexlist) {
751
$temphtml .= month_week_item($items{$index}, qq|$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day|, ($index>=1E6));
752
$i++;
753
}
754
$temphtml .= qq|&nbsp;<br>\n| if ($i==0);
755
$temphtml .= qq|</td></tr></table></td>\n|;
756
757
$html =~ s/\@\@\@DAY$x\@\@\@/$temphtml/;
758
}
759
760
httpprint([],
761
[htmlheader(), htmlplugin($config{'header_pluginfile'}),
762
$html,
763
htmlplugin($config{'footer_pluginfile'}), htmlfooter(2)] );
764
}
765
766
# print an item in the month or week view
767
sub month_week_item {
768
my ($r_item, $daylink, $is_global) = @_;
769
770
my ($eventtime, $eventlink, $eventemail);
771
if (${$r_item}{'starthourmin'} ne "0") {
772
$eventtime = hourmin2str(${$r_item}{'starthourmin'}, $prefs{'hourformat'});
773
if (${$r_item}{'endhourmin'} ne "0") {
774
$eventtime .= qq|-| . hourmin2str(${$r_item}{'endhourmin'}, $prefs{'hourformat'});
775
}
776
} else {
777
$eventtime="#";
778
}
779
$eventtime=qq|<font color="#c00000">$eventtime</font>&nbsp;|;
780
781
if (${$r_item}{'link'}) {
782
my $link=${$r_item}{'link'}; $link=~s/\%THISSESSION\%/$thissession/;
783
$eventlink = qq|&nbsp;|. iconlink("cal-link.gif", "${$r_item}{'link'}", qq|href="$link" target="_blank"|);
784
}
785
if (${$r_item}{'email'}) {
786
$eventemail = qq|&nbsp;|. iconlink("email.gif", "${$r_item}{'email'}", "");
787
}
788
789
my $s=${$r_item}{'string'};
790
my $nohtml=$s; $nohtml=~ s/<.*?>//g;
791
$s=substr($nohtml, 0, 76)."..." if (length($nohtml)>80);
792
$s="$s *" if ($is_global);
793
794
my $colorstr='';
795
if (defined($eventcolors{${$r_item}{'eventcolor'}})) {
796
$colorstr=qq|bgcolor="#$eventcolors{${$r_item}{'eventcolor'}}"|;
797
}
798
799
my $temphtml=qq|<table $colorstr cellspacing=1 cellpadding=0 width="100%"><tr><td>|.
800
"$eventtime$s$eventlink$eventemail".
801
qq|</td></tr></table>|;
802
803
return($temphtml);
804
}
805
########## END WEEKVIEW ##########################################
806
807
########## DAYVIEW ###############################################
808
sub dayview {
809
my ($year, $month, $day)=@_;
810
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
811
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
812
813
my $localtime=ow::datetime::time_gm2local(time(), $prefs{'timeoffset'}, $prefs{'daylightsaving'});
814
my ($current_year, $current_month, $current_day)=(ow::datetime::seconds2array($localtime))[5,4,3];
815
$current_year+=1900; $current_month++;
816
817
$year = $current_year if (!$year);
818
$month = $current_month if (!$month);
819
$day = $current_day if (!$day);
820
$year=2037 if ($year>2037); $year=1970 if ($year<1970);
821
$month=12 if ($month>12); $month=1 if ($month<1);
822
$day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
823
824
my ($html, $temphtml);
825
$html = applystyle(readtemplate("dayview.template").
826
readtemplate("calpopup.js").
827
readtemplate("validate.js") );
828
829
$temphtml = startform(-name=>'dateselform',
830
-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
831
ow::tool::hiddens(action=>'calday',
832
sessionid=>$thissession,
833
folder=>$folder,
834
message_id=>$messageid);
835
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/g;
836
837
$temphtml = iconlink("cal-popup.gif", $lang_text{'calendar'}, qq|href="#" onClick="calPopup(this,'mypopupCal',-175,15,'dateselform','submit_changed_dateselform');"|);
838
$temphtml .= qq|&nbsp;$lang_text{'calfmt_yearmonthday'}|;
839
$html =~ s/\@\@\@DATESELMENU\@\@\@/$temphtml/g;
840
841
$temphtml = popup_menu(-name=>'year',
842
-values=>[1970..2037],
843
-default=>$year,
844
-onChange=>"submit()",
845
-accesskey=>'G',
846
-override=>'1');
847
$html =~ s/\@\@\@YEAR\@\@\@/ $temphtml /;
848
849
$temphtml = popup_menu(-name=>'month',
850
-values=>[1..12],
851
-labels=>\%lang_month,
852
-default=>$month,
853
-onChange=>"submit()",
854
-accesskey=>'G',
855
-override=>'1');
856
$html =~ s/\@\@\@MONTH_STR\@\@\@/ $temphtml /;
857
858
$temphtml = popup_menu(-name=>'day',
859
-values=>[1..$days_in_month[$month]],
860
-default=>$day,
861
-onChange=>"submit()",
862
-accesskey=>'G',
863
-override=>'1');
864
$html =~ s/\@\@\@DAY\@\@\@/ $temphtml /;
865
866
$temphtml = end_form();
867
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
868
869
my $cal_url=qq|$config{'ow_cgiurl'}/openwebmail-cal.pl?sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid|;
870
871
$temphtml = calbuttonsstr($cal_url, $year, $month, $day);
872
if ($year!=$current_year || $month!=$current_month || $day!=$current_day) {
873
$temphtml .= iconlink("refresh.gif", "$lang_text{'backto'} ".formatted_date($current_year,$current_month,$current_day), qq|accesskey="R" href="$cal_url&amp;action=calday&amp;year=$current_year&amp;month=$current_month&amp;day=$current_day"|);
874
}
875
$temphtml .= "&nbsp;\n$miscbuttonsstr";
876
$html =~ s/\@\@\@MENUBARLINKS\@\@\@/$temphtml/g;
877
878
my $time = ow::datetime::array2seconds(0,0,12, $day,$month-1,$year-1900);
879
880
my $today = ow::datetime::array2seconds(0,0,12, $current_day,$current_month-1,$current_year-1900);
881
$temphtml=int(($time-$today)/86400);
882
$temphtml="+$temphtml" if ($temphtml>=0);
883
$html =~ s/\@\@\@DAYDIFF\@\@\@/$temphtml/g;
884
885
my ($prev_year, $prev_month, $prev_day)=(ow::datetime::seconds2array($time-86400))[5,4,3];
886
$prev_year+=1900; $prev_month++;
887
my $gif="left.gif"; $gif="right.gif" if ($ow::lang::RTL{$prefs{'language'}});
888
$temphtml=iconlink($gif, formatted_date($prev_year,$prev_month,$prev_day), qq|accesskey="U" href="$cal_url&amp;action=calday&amp;year=$prev_year&amp;month=$prev_month&amp;day=$prev_day"|). qq| \n|;
889
$html =~ s/\@\@\@PREV_LINK\@\@\@/$temphtml/g;
890
891
my ($next_year, $next_month, $next_day)=(ow::datetime::seconds2array($time+86400))[5,4,3];
892
$next_year+=1900; $next_month++;
893
$gif="right.gif"; $gif="left.gif" if ($ow::lang::RTL{$prefs{'language'}});
894
$temphtml=iconlink($gif, formatted_date($next_year,$next_month,$next_day), qq|accesskey="D" href="$cal_url&amp;action=calday&amp;year=$next_year&amp;month=$next_month&amp;day=$next_day"|). qq| \n|;
895
$html =~ s/\@\@\@NEXT_LINK\@\@\@/$temphtml/g;
896
897
898
my (%items, %indexes);
899
my $calbookfile=dotpath('calendar.book');
900
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
901
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
902
}
903
if ($prefs{'calendar_reminderforglobal'}) {
904
readcalbook("$config{'global_calendarbook'}", \%items, \%indexes, 1E6);
905
if ($prefs{'calendar_holidaydef'} eq 'auto') {
906
readcalbook("$config{'ow_holidaysdir'}/$prefs{'language'}", \%items, \%indexes, 1E7);
907
} elsif ($prefs{'calendar_holidaydef'} ne 'none') {
908
readcalbook("$config{'ow_holidaysdir'}/$prefs{'calendar_holidaydef'}", \%items, \%indexes, 1E7);
909
}
910
}
911
912
my $t=ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
913
my $wdaynum=(ow::datetime::seconds2array($t))[6];
914
915
$temphtml = formatted_date($year, $month, $day, $wdaynum);
916
if ($prefs{'charset'} eq "big5" || $prefs{'charset'} eq "gb2312") {
917
$temphtml .= qq| &nbsp; |.lunar_str($year, $month, $day, $prefs{'charset'});
918
}
919
$html =~ s/\@\@\@CALTITLE\@\@\@/$temphtml/g;
920
921
# Find all indexes that take place today and sort them by starthourmin
922
my $dow = $ow::datetime::wday_en[$wdaynum];
923
my $date = sprintf("%04d%02d%02d", $year, $month, $day);
924
my $date2 = sprintf("%04d,%02d,%02d,%s", $year,$month,$day,$dow);
925
926
my @indexlist = (); # an index list of how many events occur on this day
927
foreach ($date, '*') {
928
next if (!defined($indexes{$_}));
929
foreach my $index (@{$indexes{$_}}) {
930
if ($date =~/$items{$index}{'idate'}/ ||
931
$date2=~/$items{$index}{'idate'}/ ||
932
ow::datetime::easter_match($year,$month,$day,$items{$index}{'idate'}) ) {
933
push(@indexlist, $index);
934
}
935
}
936
}
937
@indexlist=sort { $items{$a}{'starthourmin'}<=>$items{$b}{'starthourmin'} ||
938
$items{$a}{'endhourmin'}<=>$items{$b}{'endhourmin'} ||
939
$b<=>$a } @indexlist;
940
941
my @bgcolor=($style{"tablerow_light"}, $style{"tablerow_dark"});
942
my $colornum=0;
943
$temphtml='';
944
945
my (@allday_indexies, @matrix, %layout, $slotmin, $slotmax, $colmax, );
946
build_event_matrix(\%items, \@indexlist,
947
\@allday_indexies, \@matrix, \%layout, \$slotmin, \$slotmax, \$colmax);
948
949
$colornum=($colornum+1)%2; # alternate the bgcolor
950
$temphtml .= qq|<tr>|.
951
qq|<td colspan="2">|.
952
qq|<!-- THE OUTSIDE-MOST TABLE DECLARATION FOR OUR CALENDAR DATA -->|.
953
qq|<table width="100%" cellpadding="0" cellspacing="1" border="0">\n|.
954
qq|<!-- BEGIN LISTING ALL DAY EVENTS -->|.
955
qq|<tr>|.
956
qq|<td width="10%" bgcolor=$style{'columnheader'} align="center" nowrap>$lang_text{'allday'}</td>|.
957
qq|<td width="90%" bgcolor=$style{'columnheader'} colspan="|.($colmax+1).qq|">|.
958
qq|<table width="100%" cellpadding="0" cellspacing="0">\n|;
959
960
my ($bgcolorstr, $bdstylestr, $eventlink, $eventemail, $eventtime);
961
962
for my $index (@allday_indexies) {
963
my $r_event=$items{$index};
964
965
# we do the all day events first because they're the easiest
966
($eventtime, $eventlink, $eventemail) = ('', '', '');
967
968
if (${$r_event}{'eventcolor'} eq "none") {
969
$bgcolorstr = qq|bgcolor=$style{'columnheader'}|;
970
} else {
971
$bgcolorstr = qq|bgcolor="#|. $eventcolors{${$r_event}{'eventcolor'}}. qq|"|;
972
}
973
if (${$r_event}{'starthourmin'} ne "0") {
974
$eventtime = hourmin2str(${$r_event}{'starthourmin'}, $prefs{'hourformat'});
975
if (${$r_event}{'endhourmin'} ne "0") {
976
$eventtime .= qq|-| . hourmin2str(${$r_event}{'endhourmin'}, $prefs{'hourformat'});
977
}
978
} else {
979
$eventtime = "#";
980
}
981
$eventtime=qq|<font color="#c00000">$eventtime</font>&nbsp;|;
982
983
if (${$r_event}{'link'}) {
984
my $link=${$r_event}{'link'}; $link=~s/\%THISSESSION\%/$thissession/;
985
$eventlink = qq|&nbsp;|. iconlink("cal-link.gif", "${$r_event}{'link'}", qq|href="$link" target="_blank"|);
986
}
987
if (${$r_event}{'email'}) {
988
$eventemail = qq|&nbsp;|. iconlink("email.gif", "${$r_event}{'email'}", "");
989
}
990
my ($jsedit, $jsdel)=('','');
991
if (${$r_event}{'idate'}=~/[\*|,|\|]/) {
992
$jsedit = qq|onclick="return confirm('$lang_text{multieditconf}')"|;
993
$jsdel = qq|onclick="return confirm('$lang_text{multidelconf}')"|;
994
} else {
995
$jsdel = qq|onclick="return confirm('$lang_text{caldelconf}')"|;
996
}
997
998
$temphtml .= qq|<tr>|.
999
qq|<td bgcolor=$bgcolor[$colornum] valign="top" colspan="|.($colmax+1).qq|">\n|.
1000
qq|<table width="100%" cellpadding="2" cellspacing="0"><tr><td $bgcolorstr valign="top" align="left">|;
1001
if ($index>=1E6) {
1002
$temphtml .= qq|$eventtime${$r_event}{'string'} *|.
1003
$eventlink.$eventemail;
1004
} else {
1005
$temphtml .= qq|<a accesskey="E" title="$lang_text{'edit'}" href="$cal_url&amp;|.
1006
qq|action=caledit&amp;year=$year&amp;month=$month&amp;day=$day&amp;index=$index" $jsedit>|.
1007
qq|$eventtime${$r_event}{'string'}</a>|.
1008
$eventlink.$eventemail.
1009
qq|&nbsp;&nbsp;|. iconlink("cal-delete.gif", "$lang_text{'delete'}", qq|href="$cal_url&amp;action=caldel&amp;year=$year&amp;month=$month&amp;day=$day&amp;index=$index" $jsdel|);
1010
}
1011
$temphtml .= qq|</td></tr></table>|.
1012
qq|</td>|.
1013
qq|</tr>|;
1014
}
1015
1016
if ($#indexlist < 0) {
1017
$temphtml .= qq|<tr>|.
1018
qq|<td bgcolor=$style{'columnheader'} align=center colspan="|.($colmax+1).qq|">$lang_text{'noitemforthisday'}</td>|.
1019
qq|</tr>\n|;
1020
} elsif ($#allday_indexies < 0) {
1021
$temphtml .= qq|<tr>|.
1022
qq|<td bgcolor=$style{'columnheader'} align=center colspan="|.($colmax+1).qq|">&nbsp;</td>|.
1023
qq|</tr>\n|;
1024
}
1025
1026
$temphtml .= qq|</table>|.
1027
qq|</td>|.
1028
qq|</tr>|.
1029
qq|<!--END OF ALL DAY LISTINGS-->|;
1030
1031
1032
$temphtml .= qq|<!--START EVENT MATRIX-->|;
1033
1034
my $slots_in_hour=int(60/($prefs{'calendar_interval'}||30)+0.999999);
1035
1036
for (my $slot = 0; $slot < $#slottime; $slot++) {
1037
if ($slot % $slots_in_hour==0) {
1038
1039
# skip too earily time slots
1040
my $is_earily=1;
1041
for my $i (0..$slots_in_hour-1) {
1042
if ($slot+$i >= $slotmin ||
1043
$slottime[$slot+$i] ge $prefs{'calendar_starthour'}) {
1044
$is_earily=0; last;
1045
}
1046
}
1047
1048
if ($is_earily) {
1049
$slot=$slot+$slots_in_hour-1; next; # skip $slots_in_hour slots at once
1050
}
1051
1052
# skip empty time slots
1053
if (!$prefs{'calendar_showemptyhours'}) {
1054
my $is_empty=1;
1055
for my $col (0..$colmax) {
1056
for my $i (0..$slots_in_hour-1) {
1057
if ( defined($matrix[$slot+$i][$col]) && $matrix[$slot+$i][$col] ) {
1058
$is_empty=0; last;
1059
}
1060
last if (!$is_empty);
1061
}
1062
last if (!$is_empty);
1063
}
1064
if ($is_empty) {
1065
$slot=$slot+$slots_in_hour-1; next; # skip $slots_in_hour slots at once
1066
}
1067
}
1068
1069
last if ($slot > $slotmax && $slottime[$slot] gt $prefs{'calendar_endhour'});
1070
1071
# start html for a full row
1072
$colornum = ($colornum+1)%2; # alternate the bgcolor
1073
$temphtml .= qq|<tr>|.
1074
qq|<td width="10%" bgcolor=$bgcolor[$colornum] align="right" valign=top nowrap>|.
1075
hourmin2str($slottime[$slot], $prefs{'hourformat'}).
1076
qq|</td>|;
1077
} else {
1078
my $s="&nbsp;";
1079
if ($slots_in_hour>3 && ($slot%$slots_in_hour)%2==0) {
1080
$s=qq|<font color=#c0c0c0>|.
1081
(($slot%$slots_in_hour)*$prefs{'calendar_interval'}).
1082
qq|</font>|;
1083
}
1084
# start html for non hour row
1085
$temphtml .= qq|<tr>|.
1086
qq|<td width="10%" bgcolor=$bgcolor[$colornum] valign="top" align="right">|.
1087
$s.
1088
qq|</td>|;
1089
}
1090
1091
for my $col (0..$colmax) {
1092
if (defined($matrix[$slot][$col])) {
1093
my $index=$matrix[$slot][$col];
1094
my $r_event=$items{$index};
1095
1096
if ($slot==$layout{$index}{'startslot'} &&
1097
$col==$layout{$index}{'startcol'} ) { # an event started at this cell
1098
($eventtime, $eventlink, $eventemail) = ('', '', '');
1099
1100
if (${$r_event}{'eventcolor'} ne "none") {
1101
$bgcolorstr = qq|bgcolor="#|. $eventcolors{${$r_event}{'eventcolor'}}. qq|"|;
1102
if (${$r_event}{'endhourmin'} ne '0') {
1103
$bdstylestr = qq|style="border-width: 1px; border-style: solid; border-color: #|.
1104
bordercolor($eventcolors{${$r_event}{'eventcolor'}}).
1105
qq|;"|;
1106
} else {
1107
$bdstylestr = '';
1108
}
1109
} else {
1110
$bgcolorstr = qq|bgcolor=$bgcolor[$colornum]|;
1111
if (${$r_event}{'endhourmin'} ne '0') {
1112
$bdstylestr = qq|style="border-width: 1px; border-style: solid; border-color: #666666;"|;
1113
} else {
1114
$bdstylestr = '';
1115
}
1116
}
1117
1118
$eventtime = hourmin2str(${$r_event}{'starthourmin'}, $prefs{'hourformat'});
1119
if (${$r_event}{'endhourmin'} ne "0") {
1120
$eventtime .= qq|-| . hourmin2str(${$r_event}{'endhourmin'}, $prefs{'hourformat'});
1121
}
1122
$eventtime=qq|<font color="#c00000">$eventtime</font>&nbsp;|;
1123
1124
if (${$r_event}{'link'}) {
1125
my $link=${$r_event}{'link'}; $link=~s/\%THISSESSION\%/$thissession/;
1126
$eventlink = qq|&nbsp;|. iconlink("cal-link.gif", "${$r_event}{'link'}", qq|href="$link" target="_blank"|);
1127
}
1128
if (${$r_event}{'email'}) {
1129
$eventemail = qq|&nbsp;|. iconlink("email.gif", "${$r_event}{'email'}", "");
1130
}
1131
my ($jsedit, $jsdel)=('','');
1132
if (${$r_event}{'idate'}=~/[\*|,|\|]/) {
1133
$jsedit = qq|onclick="return confirm('$lang_text{multieditconf}')"|;
1134
$jsdel = qq|onclick="return confirm('$lang_text{multidelconf}')"|;
1135
} else {
1136
$jsdel = qq|onclick="return confirm('$lang_text{caldelconf}')"|;
1137
}
1138
$temphtml .= qq|<td $bgcolorstr $bdstylestr valign="top" width="|.
1139
int(100 * $layout{$index}{'colspan'}/($colmax+1)).
1140
qq|%" rowspan="$layout{$index}{'rowspan'}" colspan="$layout{$index}{'colspan'}">|;
1141
if ($index > 1E6) {
1142
$temphtml .=qq|$eventtime ${$r_event}{'string'} *|.
1143
$eventlink.$eventemail;
1144
} else {
1145
$temphtml .= qq|<a accesskey="E" title="$lang_text{'edit'}" href="$cal_url&amp;|.
1146
qq|action=caledit&amp;year=$year&amp;month=$month&amp;day=$day&amp;index=$index" $jsedit>|.
1147
qq|$eventtime ${$r_event}{'string'}</a>|.
1148
$eventlink.$eventemail.
1149
qq|&nbsp;&nbsp;|. iconlink("cal-delete.gif", "$lang_text{'delete'}", qq|href="$cal_url&amp;action=caldel&amp;year=$year&amp;month=$month&amp;day=$day&amp;index=$index" $jsdel|);
1150
}
1151
$temphtml .= qq|</td>|;
1152
} else {
1153
# event in this cell has been drawed, nothing to do
1154
}
1155
1156
} else {
1157
# no event in this cell
1158
$temphtml .= qq|<td bgcolor=$bgcolor[$colornum]>&nbsp;</td>|;
1159
}
1160
}
1161
$temphtml .= qq|</tr>|;
1162
}
1163
1164
$temphtml .= qq|</table></td></tr>\n|;
1165
1166
$html =~ s/\@\@\@CALENDARITEMS\@\@\@/$temphtml/;
1167
1168
# replace @@@ labels with $lang vars
1169
$temphtml=qq|'$lang_wday{0}','$lang_wday{1}','$lang_wday{2}','$lang_wday{3}','$lang_wday{4}','$lang_wday{5}','$lang_wday{6}'|;
1170
$html =~ s/\@\@\@WDAY_ARRAY\@\@\@/$temphtml/;
1171
$temphtml=qq|'$lang_order{1}','$lang_order{2}','$lang_order{3}','$lang_order{4}','$lang_order{5}'|;
1172
$html =~ s/\@\@\@WORDER_ARRAY\@\@\@/$temphtml/;
1173
$temphtml=qq|'$lang_wday_abbrev{0}','$lang_wday_abbrev{1}','$lang_wday_abbrev{2}','$lang_wday_abbrev{3}','$lang_wday_abbrev{4}','$lang_wday_abbrev{5}','$lang_wday_abbrev{6}'|;
1174
$html =~ s/\@\@\@WDAYABBREV_ARRAY\@\@\@/$temphtml/;
1175
$temphtml=qq|'$lang_month{1}','$lang_month{2}','$lang_month{3}','$lang_month{4}','$lang_month{5}','$lang_month{6}','$lang_month{7}','$lang_month{8}','$lang_month{9}','$lang_month{10}','$lang_month{11}','$lang_month{12}'|;
1176
$html =~ s/\@\@\@WMONTH_ARRAY\@\@\@/$temphtml/;
1177
$html =~ s/\@\@\@WSTART\@\@\@/$prefs{'calendar_weekstart'}/g;
1178
$html =~ s/\@\@\@TODAY\@\@\@/$lang_text{'today'}/g;
1179
$html =~ s/\@\@\@THISDAY_ONLY\@\@\@/$lang_text{'thisday_only'}/g;
1180
$html =~ s/\@\@\@THE_WDAY_OF_THISMONTH\@\@\@/$lang_text{'the_wday_of_thismonth'}/g;
1181
$html =~ s/\@\@\@EVERY_WDAY_THISMONTH\@\@\@/$lang_text{'every_wday_thismonth'}/g;
1182
$html =~ s/\@\@\@EVERY_ODDMONTH_THISYEAR\@\@\@/$lang_text{'every_oddmonth_thisyear'}/g;
1183
$html =~ s/\@\@\@EVERY_EVENMONTH_THISYEAR\@\@\@/$lang_text{'every_evenmonth_thisyear'}/g;
1184
# replace @@@ labels with runtime js variable
1185
$html =~ s/\@\@\@ORDER\@\@\@/"+wOrder[(weekOrder-1)]+"/g;
1186
$html =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/g;
1187
1188
$temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
1189
-name=>'additemform',
1190
-override=>'1').
1191
ow::tool::hiddens(sessionid=>$thissession,
1192
folder=>$folder,
1193
message_id=>$messageid,
1194
action=>'caladd');
1195
$html =~ s/\@\@\@STARTADDITEMFORM\@\@\@/$temphtml/;
1196
1197
$temphtml = iconlink("cal-popup.gif", $lang_text{'calendar'}, qq|href="#" onClick="calPopup(this,'mypopupCal',-175,15,'additemform','valiDate');"|);
1198
$temphtml .= qq|&nbsp; $lang_text{'calfmt_yearmonthday'}|;
1199
$html =~ s/\@\@\@ITEMDATEMENU\@\@\@/$temphtml/g;
1200
1201
$temphtml = popup_menu(-name=>'year',
1202
-values=>[1970..2037],
1203
-onChange=>"valiDate('additemform')",
1204
-default=>$year,
1205
-override=>'1');
1206
$html =~ s/\@\@\@YEAR\@\@\@/$temphtml/g;
1207
1208
$temphtml = popup_menu(-name=>'month',
1209
-values=>[1..12],
1210
-default=>$month,
1211
-onChange=>"valiDate('additemform')",
1212
-labels=>\%lang_month,
1213
-override=>1);
1214
$html =~ s/\@\@\@MONTH_STR\@\@\@/$temphtml/g;
1215
1216
$temphtml = popup_menu(-name=>'day',
1217
-values=>[1..31],
1218
-default=>$day,
1219
-onChange=>"valiDate('additemform')",
1220
-override=>'1');
1221
$html =~ s/\@\@\@DAY\@\@\@/$temphtml/g;
1222
1223
1224
$temphtml = textfield(-name=>'string',
1225
-default=>'',
1226
-size=>'32',
1227
-accesskey=>'I',
1228
-override=>'1');
1229
$html =~ s/\@\@\@STRINGFIELD\@\@\@/$temphtml/;
1230
1231
my @hourlist;
1232
if ($prefs{'hourformat'}==12) {
1233
@hourlist=qw(none 12 1 2 3 4 5 6 7 8 9 10 11);
1234
} else {
1235
@hourlist=qw(none 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23);
1236
}
1237
my %numlabels=( none=>$lang_text{'none'},
1238
0=>'00', 1=>'01', 2=>'02', 3=>'03', 4=>'04',
1239
5=>'05', 6=>'06', 7=>'07', 8=>'08', 9=>'09');
1240
my $temphtml2;
1241
1242
$temphtml = $lang_text{'calfmt_hourminampm'};
1243
$temphtml2 = popup_menu(-name=>'starthour',
1244
-values=>\@hourlist,
1245
-default=>'none',
1246
-labels=>\%numlabels,
1247
-override=>'1');
1248
$temphtml2 .= " <B>:</B> ";
1249
$temphtml2 .= popup_menu(-name=>'startmin',
1250
-values=>[0,5,10,15,20,25,30,35,40,45,50,55],
1251
-default=>0,
1252
-labels=>\%numlabels,
1253
-override=>'1');
1254
$temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
1255
if ($prefs{'hourformat'}==12) {
1256
$temphtml2 = popup_menu(-name=>'startampm',
1257
-values=>['am','pm'],
1258
-default=>'am',
1259
-labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
1260
-override=>'1' );
1261
} else {
1262
$temphtml2 ="";
1263
}
1264
$temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
1265
$html =~ s/\@\@\@STARTHOURMINMENU\@\@\@/$temphtml/;
1266
1267
$temphtml = $lang_text{'calfmt_hourminampm'};
1268
$temphtml2 = popup_menu(-name=>'endhour',
1269
-values=>\@hourlist,
1270
-default=>'none',
1271
-labels=>\%numlabels,
1272
-override=>'1');
1273
$temphtml2 .= " <B>:</B> ";
1274
$temphtml2 .= popup_menu(-name=>'endmin',
1275
-values=>[0,5,10,15,20,25,30,35,40,45,50,55],
1276
-default=>0,
1277
-labels=>\%numlabels,
1278
-override=>'1');
1279
$temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
1280
if ($prefs{'hourformat'}==12) {
1281
$temphtml2 = popup_menu(-name=>'endampm',
1282
-values=>['am','pm'],
1283
-default=>'am',
1284
-labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
1285
-override=>'1' );
1286
} else {
1287
$temphtml2 ="";
1288
}
1289
$temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
1290
$html =~ s/\@\@\@ENDHOURMINMENU\@\@\@/$temphtml/;
1291
1292
1293
# recurrance event section
1294
my $weekorder=int(($day+6)/7);
1295
my %wdaynum = qw (Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6);
1296
my %dayfreqlabels = ('thisdayonly' =>$lang_text{'thisday_only'},
1297
'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
1298
'everywdaythismonth'=>$lang_text{'every_wday_thismonth'});
1299
$dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@ORDER\@\@\@/$lang_order{$weekorder}/;
1300
$dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum{$dow}}/;
1301
$dayfreqlabels{'everywdaythismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum{$dow}}/;
1302
1303
if ($weekorder<=4) {
1304
$temphtml = popup_menu(-name=>'dayfreq',
1305
-values=>['thisdayonly', 'thewdayofthismonth', 'everywdaythismonth'],
1306
-default=>'thisdayonly',
1307
-labels=>\%dayfreqlabels,
1308
-override=>'1');
1309
} else {
1310
$temphtml = popup_menu(-name=>'dayfreq',
1311
-values=>['thisdayonly', 'everywdaythismonth'],
1312
-default=>'thisdayonly',
1313
-labels=>\%dayfreqlabels,
1314
-override=>'1');
1315
}
1316
$html =~ s/\@\@\@FREQMENU\@\@\@/$temphtml/;
1317
1318
$temphtml = checkbox(-name=>'thisandnextndays',
1319
-value=>'1',
1320
-checked=>0,
1321
-label=>'',
1322
-override=>'1');
1323
$html =~ s/\@\@\@THISANDNEXTNDAYSCHECKBOX\@\@\@/$temphtml/g;
1324
1325
$temphtml = textfield(-name=>'ndays',
1326
-default=>'',
1327
-size=>'2',
1328
-override=>'1');
1329
$html =~ s/\@\@\@NDAYSFIELD\@\@\@/$temphtml/;
1330
1331
my %monthfreqlabels = ('thismonthonly' =>$lang_text{'thismonth_only'},
1332
'everyoddmonththisyear' =>$lang_text{'every_oddmonth_thisyear'},
1333
'everyevenmonththisyear'=>$lang_text{'every_evenmonth_thisyear'},
1334
'everymonththisyear' =>$lang_text{'every_month_thisyear'});
1335
my @monthfreq =('thismonthonly');
1336
if ($month%2==1) {
1337
push(@monthfreq, 'everyoddmonththisyear');
1338
} else {
1339
push(@monthfreq, 'everyevenmonththisyear');
1340
}
1341
push(@monthfreq, 'everymonththisyear');
1342
$temphtml = popup_menu(-name=>'monthfreq',
1343
-values=>\@monthfreq,
1344
-default=>'thismonthonly',
1345
-labels=>\%monthfreqlabels,
1346
-override=>'1');
1347
$html =~ s/\@\@\@MONTHFREQMENU\@\@\@/$temphtml/g;
1348
1349
$temphtml = checkbox(-name=>'everyyear',
1350
-value=>'1',
1351
-checked=>0,
1352
-label=>'',
1353
-override=>'1');
1354
$html =~ s/\@\@\@EVERYYEARCHECKBOX\@\@\@/$temphtml/g;
1355
1356
$temphtml = textfield(-name=>'link',
1357
-default=>'http://',
1358
-size=>'32',
1359
-override=>'1');
1360
$html =~ s/\@\@\@LINKFIELD\@\@\@/$temphtml/;
1361
1362
if ($config{'calendar_email_notifyinterval'} > 0 ) {
1363
templateblock_enable($html, 'EMAIL');
1364
$temphtml = textfield(-name=>'email',
1365
-default=>'',
1366
-size=>'32',
1367
-override=>'1');
1368
$html =~ s/\@\@\@EMAILFIELD\@\@\@/$temphtml/;
1369
} else {
1370
templateblock_disable($html, 'EMAIL');
1371
}
1372
1373
$temphtml = popup_menu(-name=>'eventcolor',
1374
-values=>['none', sort keys %eventcolors],
1375
-default=>'none',
1376
-labels=>{ none => $lang_text{'none'} },
1377
-override=>'1');
1378
$html =~ s/\@\@\@EVENTCOLORMENU\@\@\@/$temphtml/;
1379
1380
$temphtml = qq|<table align="center" height="25">|;
1381
my $eventcolornum = 1;
1382
foreach (sort keys %eventcolors) {
1383
$temphtml .= qq|<td width=14 align=center bgcolor="#$eventcolors{$_}">|.
1384
qq|<a href="#" onClick='javascript:document.additemform.eventcolor.selectedIndex="$eventcolornum"'>$_</a></td>\n|;
1385
$eventcolornum++;
1386
}
1387
$temphtml .= qq|<td width=14 align=center">|.
1388
qq|<a href="#" onClick='javascript:document.additemform.eventcolor.selectedIndex="0"'>--</a></td>\n|;
1389
$temphtml .= qq|</tr></table>|;
1390
$html =~ s/\@\@\@COLORTABLE\@\@\@/$temphtml/;
1391
1392
$temphtml = submit(-name=>'savebutton',
1393
-accesskey=>'I',
1394
-value=>$lang_text{'save'});
1395
$html =~ s/\@\@\@SUBMITBUTTON\@\@\@/$temphtml/;
1396
1397
$temphtml = end_form();
1398
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
1399
1400
httpprint([],
1401
[htmlheader(), htmlplugin($config{'header_pluginfile'}),
1402
$html,
1403
htmlplugin($config{'footer_pluginfile'}), htmlfooter(2)] );
1404
}
1405
1406
sub build_event_matrix {
1407
my ($r_items, $r_indexlist,
1408
$r_allday_indexies, $r_matrix, $r_layout, $r_slotmin, $r_slotmax, $r_colmax)=@_;
1409
my @matrix_indexies;
1410
my %slots;
1411
(${$r_slotmin}, ${$r_slotmax}, ${$r_colmax})=(999999, 0, 0);
1412
1413
# split the events into two lists: all day events, and not all day events.
1414
foreach my $index (@{$r_indexlist}) {
1415
my $r_event=${$r_items}{$index};
1416
if ( (${$r_event}{'starthourmin'} gt ${$r_event}{'endhourmin'} && ${$r_event}{'endhourmin'} ne '0') ||
1417
(${$r_event}{'starthourmin'} eq '0' && ${$r_event}{'endhourmin'} eq '0') ) {
1418
push(@{$r_allday_indexies}, $index);
1419
} else {
1420
push(@matrix_indexies, $index);
1421
}
1422
}
1423
1424
foreach my $index (@matrix_indexies) {
1425
my $r_event=${$r_items}{$index};
1426
next if (${$r_event}{'endhourmin'} ne '0' &&
1427
${$r_event}{'starthourmin'} gt ${$r_event}{'endhourmin'});
1428
# find all slots of this event
1429
for (my $slot = 0; $slot < $#slottime; $slot++) {
1430
if ((${$r_event}{'endhourmin'} gt $slottime[$slot] &&
1431
${$r_event}{'starthourmin'} lt $slottime[$slot+1]) ||
1432
((${$r_event}{'endhourmin'} eq '0' ||
1433
${$r_event}{'endhourmin'} eq ${$r_event}{'starthourmin'}) &&
1434
${$r_event}{'starthourmin'} ge $slottime[$slot] &&
1435
${$r_event}{'starthourmin'} lt $slottime[$slot+1]) ) {
1436
push(@{$slots{$index}}, $slot);
1437
${$r_layout}{$index}{'rowspan'}++;
1438
${$r_slotmin}=$slot if ($slot<${$r_slotmin});
1439
${$r_slotmax}=$slot if ($slot>${$r_slotmax});
1440
}
1441
}
1442
1443
# find the first available column for this event so all it won't conflict with other event
1444
my $col=0;
1445
for ($col=0; ; $col++) {
1446
my $col_available=1;
1447
foreach my $slot (@{$slots{$index}}) {
1448
if (defined(${$r_matrix}[$slot][$col]) && ${$r_matrix}[$slot][$col]) {
1449
$col_available=0; last;
1450
}
1451
}
1452
last if ($col_available);
1453
}
1454
${$r_layout}{$index}{'colspan'}=1;
1455
1456
foreach my $slot (@{$slots{$index}}) {
1457
${$r_matrix}[$slot][$col]=$index;
1458
}
1459
${$r_layout}{$index}{'startslot'}=${$slots{$index}}[0];
1460
${$r_layout}{$index}{'startcol'}=$col;
1461
${$r_colmax}=$col if ($col>${$r_colmax});
1462
}
1463
1464
# try to enlarge this event to other columns
1465
foreach my $index (@matrix_indexies) {
1466
my $extensible=1;
1467
foreach my $slot (@{$slots{$index}}) {
1468
for my $col (${$r_layout}{$index}{'startcol'}+1..${$r_colmax}) {
1469
if (defined(${$r_matrix}[$slot][$col]) && ${$r_matrix}[$slot][$col]) {
1470
$extensible=0; last;
1471
}
1472
}
1473
last if ($extensible==0);
1474
}
1475
if ($extensible) {
1476
for my $col (${$r_layout}{$index}{'startcol'}+1..${$r_colmax}) {
1477
foreach my $slot (@{$slots{$index}}) {
1478
${$r_matrix}[$slot][$col]=$index;
1479
}
1480
${$r_layout}{$index}{'colspan'}++;
1481
}
1482
}
1483
}
1484
return;
1485
}
1486
1487
sub bordercolor {
1488
# take a hex number and calculate a hex number that
1489
# will be a nice complement to it as a bordercolor
1490
my ($redhex, $greenhex, $bluehex) = $_[0]=~/(..)(..)(..)/;
1491
my ($r, $g, $blue) = (sprintf("%d", hex($redhex)), sprintf("%d", hex($greenhex)), sprintf("%d", hex($bluehex)));
1492
my ($h, $s, $v) = rgb2hsv($r, $g, $blue);
1493
1494
# adjust to get our new hsv bordercolor
1495
if ($s > .5) { $s -= .15; $v += 30; } else { $s += .15; $v -= 30; };
1496
$s = 0 if ($s < 0);
1497
$s = 1 if ($s > 1);
1498
$v = 0 if ($v < 0);
1499
$v = 255 if ($v > 255);
1500
1501
($r, $g, $blue) = hsv2rgb($h, $s, $v);
1502
($redhex, $greenhex, $bluehex) = (sprintf("%02x", $r), sprintf("%02x", $g), sprintf("%02x", $blue));
1503
1504
return "$redhex$greenhex$bluehex";
1505
}
1506
1507
sub rgb2hsv {
1508
# based off reference code at http://www.cs.rit.edu/~ncs/color/t_convert.html
1509
my ($r, $g, $blue) = @_;
1510
my ($h, $s, $v, $min, $max, $delta);
1511
1512
($min, $max) = (sort { $a <=> $b } ($r,$g,$blue))[0,-1];
1513
return(-1, 0, 0) if ($max==0); # r g b are all 0
1514
1515
$delta = $max - $min;
1516
1517
$v = $max;
1518
$s = $delta / $max;
1519
if ($r == $max) {
1520
$h = ($g - $blue) / $delta;
1521
} elsif ($g == $max) {
1522
$h = 2 + ($blue - $r) / $delta;
1523
} else {
1524
$h = 4 + ($r - $g) / $delta;
1525
}
1526
1527
$h *= 60;
1528
$h += 360 if ($h < 0);
1529
1530
return ($h, $s, $v);
1531
}
1532
1533
sub hsv2rgb {
1534
# based off reference code at http://www.cs.rit.edu/~ncs/color/t_convert.html
1535
my ($h, $s, $v) = @_;
1536
my ($i, $f, $p, $q, $t, $r, $g, $blue);
1537
1538
return ($v, $v, $v) if ($s == 0); # achromatic
1539
1540
$h /= 60; # sector 0 to 5
1541
$i = int($h);
1542
$f = $h - $i;
1543
$p = $v * (1 - $s);
1544
$q = $v * (1 - $s * $f);
1545
$t = $v * (1 - $s * (1 - $f));
1546
1547
if ($i == 0) {
1548
($r, $g, $blue) = ($v, $t, $p);
1549
} elsif ($i == 1) {
1550
($r, $g, $blue) = ($q, $v, $p);
1551
} elsif ($i == 2) {
1552
($r, $g, $blue) = ($p, $v, $t);
1553
} elsif ($i == 3) {
1554
($r, $g, $blue) = ($p, $q, $v);
1555
} elsif ($i == 4) {
1556
($r, $g, $blue) = ($t, $p, $v);
1557
} else {
1558
($r, $g, $blue) = ($v, $p, $q);
1559
}
1560
1561
return ($r, $g, $blue);
1562
}
1563
########## END DAYVIEW ###########################################
1564
1565
########## LISTVIEW ##############################################
1566
sub listview {
1567
my $year=$_[0];
1568
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
1569
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
1570
1571
my $localtime=ow::datetime::time_gm2local(time(), $prefs{'timeoffset'}, $prefs{'daylightsaving'});
1572
my ($current_year, $current_month, $current_day)=(ow::datetime::seconds2array($localtime))[5,4,3];
1573
$current_year+=1900; $current_month++;
1574
1575
$year = $current_year if (!$year);
1576
$year=2037 if ($year>2037); $year=1970 if ($year<1970);
1577
1578
my ($html, $temphtml);
1579
$html = applystyle(readtemplate("listview.template"));
1580
1581
$temphtml = startform(-name=>'dateselform',
1582
-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl").
1583
ow::tool::hiddens(action=>'callist',
1584
sessionid=>$thissession,
1585
folder=>$folder,
1586
message_id=>$messageid);
1587
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/g;
1588
1589
$html =~ s/\@\@\@DATESELMENU\@\@\@/$lang_text{'calfmt_year'}/g;
1590
$temphtml = popup_menu(-name=>'year',
1591
-values=>[1970..2037],
1592
-default=>$year,
1593
-onChange=>"submit()",
1594
-accesskey=>'G',
1595
-override=>'1');
1596
$html =~ s/\@\@\@YEAR\@\@\@/ $temphtml /;
1597
1598
$temphtml = end_form();
1599
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
1600
1601
$temphtml = formatted_date($year);
1602
$html =~ s/\@\@\@CALTITLE\@\@\@/$temphtml/g;
1603
1604
my $cal_url=qq|$config{'ow_cgiurl'}/openwebmail-cal.pl?sessionid=$thissession&amp;folder=$escapedfolder&amp;message_id=$escapedmessageid|;
1605
1606
$temphtml = calbuttonsstr($cal_url, $current_year, $current_month, $current_day);
1607
if ($year != $current_year) {
1608
$temphtml .= iconlink("refresh.gif", "$lang_text{'backto'} ".formatted_date($current_year), qq|accesskey="R" href="$cal_url&amp;action=callist&amp;year=$current_year"|);
1609
}
1610
$temphtml .= "&nbsp;\n$miscbuttonsstr";
1611
$html =~ s/\@\@\@MENUBARLINKS\@\@\@/$temphtml/g;
1612
1613
my $prev_year = $year - 1;
1614
my $gif="left.gif"; $gif="right.gif" if ($ow::lang::RTL{$prefs{'language'}});
1615
$temphtml=iconlink($gif, formatted_date($prev_year), qq|accesskey="U" href="$cal_url&amp;action=callist&amp;year=$prev_year"|). qq| \n|;
1616
$html =~ s/\@\@\@PREV_LINK\@\@\@/$temphtml/g;
1617
1618
my $next_year = $year + 1;
1619
$gif="right.gif"; $gif="left.gif" if ($ow::lang::RTL{$prefs{'language'}});
1620
$temphtml=iconlink($gif, formatted_date($next_year), qq|accesskey="D" href="$cal_url&amp;action=callist&amp;year=$next_year"|). qq| \n|;
1621
$html =~ s/\@\@\@NEXT_LINK\@\@\@/$temphtml/g;
1622
1623
my (%items, %indexes);
1624
my $calbookfile=dotpath('calendar.book');
1625
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
1626
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
1627
}
1628
if ($prefs{'calendar_reminderforglobal'}) {
1629
readcalbook("$config{'global_calendarbook'}", \%items, \%indexes, 1E6);
1630
if ($prefs{'calendar_holidaydef'} eq 'auto') {
1631
readcalbook("$config{'ow_holidaysdir'}/$prefs{'language'}", \%items, \%indexes, 1E7);
1632
} elsif ($prefs{'calendar_holidaydef'} ne 'none') {
1633
readcalbook("$config{'ow_holidaysdir'}/$prefs{'calendar_holidaydef'}", \%items, \%indexes, 1E7);
1634
}
1635
}
1636
1637
my $t0 = ow::datetime::array2seconds(1,1,1, $current_day,$current_month-1,$current_year-1900);
1638
my @accesskey=qw(0 1 2 3 4 5 6 7 8 9 0 J Q);
1639
1640
$temphtml="";
1641
for my $month (1..12) {
1642
for my $day (1..$days_in_month[$month]) {
1643
my $t=ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
1644
my $wdaynum=(ow::datetime::seconds2array($t))[6];
1645
my $dow=$ow::datetime::wday_en[$wdaynum];
1646
my $date=sprintf("%04d%02d%02d", $year, $month, $day);
1647
my $date2=sprintf("%04d,%02d,%02d,%s", $year,$month,$day,$dow);
1648
1649
my @indexlist=();
1650
foreach ($date, '*') {
1651
next if (!defined($indexes{$_}));
1652
foreach my $index (@{$indexes{$_}}) {
1653
if ($date =~/$items{$index}{'idate'}/ ||
1654
$date2=~/$items{$index}{'idate'}/ ||
1655
ow::datetime::easter_match($year,$month,$day,$items{$index}{'idate'}) ) {
1656
push(@indexlist, $index);
1657
}
1658
}
1659
}
1660
@indexlist=sort { $items{$a}{'starthourmin'}<=>$items{$b}{'starthourmin'} ||
1661
$items{$a}{'endhourmin'}<=>$items{$b}{'endhourmin'} ||
1662
$b<=>$a } @indexlist;
1663
1664
my $dayhtml="";
1665
for my $index (@indexlist) {
1666
$dayhtml .= listview_item($index, \%items, $cal_url, "year=$year&amp;month=$month&amp;day=$day&amp;index=$index&amp;callist=1", ($index>=1E6))
1667
}
1668
1669
1670
my ($tr_bgcolorstr, $td_bgcolorstr);
1671
my $bgcolor=$style{tablerow_light};
1672
$bgcolor=$style{tablerow_dark} if ($year==$current_year && $month==$current_month && $day==$current_day);
1673
if ($prefs{'uselightbar'}) {
1674
$tr_bgcolorstr=qq|bgcolor=$bgcolor |.
1675
qq|onMouseOver='this.style.backgroundColor=$style{tablerow_hicolor};' |.
1676
qq|onMouseOut='this.style.backgroundColor=$bgcolor;' |.
1677
qq|onClick="window.location.href='$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day';"|;
1678
$td_bgcolorstr='';
1679
} else {
1680
$tr_bgcolorstr='';
1681
$td_bgcolorstr=qq|bgcolor= $bgcolor|;
1682
}
1683
1684
if ($dayhtml ne "" || $t==$t0) {
1685
my $daydiffstr=int(($t-$t0)/86400);
1686
$daydiffstr="+$daydiffstr" if ($daydiffstr>0);
1687
$dayhtml = qq|<tr><td>&nbsp;</td></tr>| if ($dayhtml eq "");
1688
$temphtml .= qq|<tr $tr_bgcolorstr>|.
1689
qq|<td $td_bgcolorstr nowrap>|.
1690
qq|<a accesskey="$accesskey[$month]" href="$cal_url&amp;action=calday&amp;year=$year&amp;month=$month&amp;day=$day"><b>|;
1691
if ($prefs{'dateformat'}=~m!mm([/\-\.])dd!) {
1692
$temphtml.=sprintf("%02d$1%02d", $month, $day);
1693
} elsif ($prefs{'dateformat'}=~m!dd([/\-\.])mm!) {
1694
$temphtml.=sprintf("%02d$1%02d", $day, $month);
1695
} else {
1696
$temphtml.=sprintf("%02d/%02d", $month, $day);
1697
}
1698
$temphtml.=qq|</b></a>|;
1699
if ($prefs{'charset'} eq "big5" || $prefs{'charset'} eq "gb2312") {
1700
$temphtml .= qq| &nbsp; |.lunar_str($year, $month, $day, $prefs{'charset'});
1701
}
1702
$temphtml .= qq|</td>|.
1703
qq|<td $td_bgcolorstr $bgcolor>|.
1704
qq|<a href="$cal_url&amp;action=calweek&amp;year=$year&amp;month=$month">|.
1705
qq|$lang_wday{$wdaynum}</a>|.
1706
qq|</td>|.
1707
qq|<td $td_bgcolorstr align="right" nowrap>$daydiffstr &nbsp;</td>|.
1708
qq|<td $td_bgcolorstr><table width="100%" cellspacing="0" cellpadding="2">$dayhtml</table></td>|.
1709
qq|</tr>\n|;
1710
}
1711
} # day loop end
1712
} # month loop end
1713
$html=~s/\@\@\@ITEMLIST\@\@\@/$temphtml/;
1714
1715
httpprint([],
1716
[htmlheader(), htmlplugin($config{'header_pluginfile'}),
1717
$html,
1718
htmlplugin($config{'footer_pluginfile'}), htmlfooter(2)] );
1719
}
1720
1721
# print an item in the listview
1722
sub listview_item {
1723
my ($index, $r_items, $cal_url, $cgi_parm, $is_global) = @_;
1724
my $r_item=${$r_items}{$index};
1725
my $temphtml;
1726
1727
my $colorstr='';
1728
if (defined($eventcolors{${$r_item}{'eventcolor'}})) {
1729
$colorstr=qq|bgcolor="#$eventcolors{${$r_item}{'eventcolor'}}"|;
1730
}
1731
1732
my ($eventtime, $eventlink, $eventemail);
1733
if (${$r_item}{'starthourmin'} ne "0") {
1734
$eventtime = hourmin2str(${$r_item}{'starthourmin'}, $prefs{'hourformat'});
1735
if (${$r_item}{'endhourmin'} ne "0") {
1736
$eventtime .= qq|-| . hourmin2str(${$r_item}{'endhourmin'}, $prefs{'hourformat'});
1737
}
1738
} else {
1739
$eventtime="#";
1740
}
1741
$eventtime=qq|<font color="#c00000">$eventtime</font>&nbsp;|;
1742
if (${$r_item}{'link'}) {
1743
my $link=${$r_item}{'link'}; $link=~s/\%THISSESSION\%/$thissession/;
1744
$eventlink = qq|&nbsp;|. iconlink("cal-link.gif", "${$r_item}{'link'}", qq|href="$link" target="_blank"|);
1745
}
1746
if (${$r_item}{'email'}) {
1747
$eventemail = qq|&nbsp;|. iconlink("email.gif", "${$r_item}{'email'}", "");
1748
}
1749
my ($jsedit, $jsdel)=('','');
1750
if (${$r_item}{'idate'}=~/[\*|,|\|]/) {
1751
$jsedit = qq|onclick="return confirm('$lang_text{multieditconf}')"|;
1752
$jsdel = qq|onclick="return confirm('$lang_text{multidelconf}')"|;
1753
} else {
1754
$jsdel = qq|onclick="return confirm('$lang_text{caldelconf}')"|;
1755
}
1756
1757
my $s=${$r_item}{'string'};
1758
my $nohtml=$s; $nohtml=~ s/<.*?>//g;
1759
$s=substr($nohtml, 0, 76)."..." if (length($nohtml)>80);
1760
1761
if ($is_global) {
1762
$temphtml.=qq|<td $colorstr width="120" nowrap>$eventtime</td>\n|.
1763
qq|<td $colorstr>$s *|.
1764
$eventlink.$eventemail.
1765
qq|</td>\n|;
1766
} else {
1767
$temphtml.=qq|<td $colorstr width="120" nowrap>$eventtime</td>\n|.
1768
qq|<td $colorstr><a title="$lang_text{'edit'}" href="$cal_url&amp;action=caledit&amp;$cgi_parm" $jsedit>$s</a>|.
1769
$eventlink.$eventemail.
1770
qq|&nbsp;&nbsp;|. iconlink("cal-delete.gif", "$lang_text{'delete'}", qq|href="$cal_url&amp;action=caldel&amp;index=$index&amp;$cgi_parm" $jsdel|).
1771
qq|</td>\n|;
1772
}
1773
$temphtml=qq|<tr $colorstr>$temphtml</tr>|;
1774
return($temphtml);
1775
}
1776
########## END LISTVIEW ##########################################
1777
1778
########## EDIT_ITEM #############################################
1779
# display the edit menu of an event
1780
sub edit_item {
1781
my ($year, $month, $day, $index)=@_;
1782
1783
my ($html, $temphtml);
1784
$html = applystyle(readtemplate("editcalendar.template").
1785
readtemplate("calpopup.js").
1786
readtemplate("validate.js") );
1787
1788
my $calbookfile=dotpath('calendar.book');
1789
1790
my (%items, %indexes);
1791
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
1792
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
1793
}
1794
if (! defined($items{$index}) ) {
1795
openwebmailerror(__FILE__, __LINE__, "$lang_text{'calendar'} $index $lang_err{'doesnt_exist'}");
1796
writelog("edit calitem error - item missing, index=$index");
1797
writehistory("edit calitem error - item missing, index=$index");
1798
}
1799
1800
# replace @@@ labels with $lang vars
1801
$temphtml=qq|'$lang_wday{0}','$lang_wday{1}','$lang_wday{2}','$lang_wday{3}','$lang_wday{4}','$lang_wday{5}','$lang_wday{6}'|;
1802
$html =~ s/\@\@\@WDAY_ARRAY\@\@\@/$temphtml/;
1803
$temphtml=qq|'$lang_order{1}','$lang_order{2}','$lang_order{3}','$lang_order{4}','$lang_order{5}'|;
1804
$html =~ s/\@\@\@WORDER_ARRAY\@\@\@/$temphtml/;
1805
$temphtml=qq|'$lang_wday_abbrev{0}','$lang_wday_abbrev{1}','$lang_wday_abbrev{2}','$lang_wday_abbrev{3}','$lang_wday_abbrev{4}','$lang_wday_abbrev{5}','$lang_wday_abbrev{6}'|;
1806
$html =~ s/\@\@\@WDAYABBREV_ARRAY\@\@\@/$temphtml/;
1807
$temphtml=qq|'$lang_month{1}','$lang_month{2}','$lang_month{3}','$lang_month{4}','$lang_month{5}','$lang_month{6}','$lang_month{7}','$lang_month{8}','$lang_month{9}','$lang_month{10}','$lang_month{11}','$lang_month{12}'|;
1808
$html =~ s/\@\@\@WMONTH_ARRAY\@\@\@/$temphtml/;
1809
$html =~ s/\@\@\@WSTART\@\@\@/$prefs{'calendar_weekstart'}/g;
1810
$html =~ s/\@\@\@TODAY\@\@\@/$lang_text{'today'}/g;
1811
$html =~ s/\@\@\@THISDAY_ONLY\@\@\@/$lang_text{'thisday_only'}/g;
1812
$html =~ s/\@\@\@THE_WDAY_OF_THISMONTH\@\@\@/$lang_text{'the_wday_of_thismonth'}/g;
1813
$html =~ s/\@\@\@EVERY_WDAY_THISMONTH\@\@\@/$lang_text{'every_wday_thismonth'}/g;
1814
$html =~ s/\@\@\@EVERY_ODDMONTH_THISYEAR\@\@\@/$lang_text{'every_oddmonth_thisyear'}/g;
1815
$html =~ s/\@\@\@EVERY_EVENMONTH_THISYEAR\@\@\@/$lang_text{'every_evenmonth_thisyear'}/g;
1816
# replace @@@ labels with runtime js variable
1817
$html =~ s/\@\@\@ORDER\@\@\@/"+wOrder[(weekOrder-1)]+"/g;
1818
$html =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/g;
1819
1820
$temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
1821
-name=>'editcalendar',
1822
-override=>'1').
1823
ow::tool::hiddens(sessionid=>$thissession,
1824
folder=>$folder,
1825
message_id=>$messageid,
1826
action=>'calupdate',
1827
index=>$index);
1828
$temphtml .= ow::tool::hiddens(callist=>'1') if (defined(param('callist')));
1829
$html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/;
1830
1831
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
1832
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
1833
$day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
1834
1835
$temphtml = qq|$lang_text{'calfmt_yearmonthday'}&nbsp; |;
1836
$temphtml .= iconlink("cal-popup.gif", $lang_text{'calendar'}, qq|href="#" onClick="calPopup(this,'editcalendarpopupCal',25,15,'editcalendar','valiDate');"|);
1837
$html =~ s/\@\@\@ITEMDATEMENU\@\@\@/$temphtml/g;
1838
1839
$temphtml = popup_menu(-name=>'year',
1840
-values=>[1970..2037],
1841
-onChange=>"valiDate('editcalendar')",
1842
-default=>$year,
1843
-override=>'1');
1844
$html =~ s/\@\@\@YEAR\@\@\@/$temphtml/g;
1845
1846
$temphtml = popup_menu(-name=>'month',
1847
-values=>[1..12],
1848
-default=>$month,
1849
-onChange=>"valiDate('editcalendar')",
1850
-labels=>\%lang_month,
1851
-override=>1);
1852
$html =~ s/\@\@\@MONTH_STR\@\@\@/$temphtml/g;
1853
1854
$temphtml = popup_menu(-name=>'day',
1855
-values=>[1..31],
1856
-default=>$day,
1857
-onChange=>"valiDate('editcalendar')",
1858
-override=>'1');
1859
$html =~ s/\@\@\@DAY\@\@\@/$temphtml/g;
1860
1861
1862
$temphtml = textfield(-name=>'string',
1863
-default=>$items{$index}{'string'},
1864
-size=>'32',
1865
-override=>'1');
1866
$html =~ s/\@\@\@STRINGFIELD\@\@\@/$temphtml/;
1867
1868
my @hourlist;
1869
if ($prefs{'hourformat'}==12) {
1870
@hourlist=qw(none 1 2 3 4 5 6 7 8 9 10 11 12);
1871
} else {
1872
@hourlist=qw(none 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23);
1873
}
1874
my %numlabels=( none=>$lang_text{'none'},
1875
0=>'00', 1=>'01', 2=>'02', 3=>'03', 4=>'04',
1876
5=>'05', 6=>'06', 7=>'07', 8=>'08', 9=>'09');
1877
my $temphtml2;
1878
1879
my ($starthour, $startmin, $startampm)=('none', 0, 'am');
1880
if ($items{$index}{'starthourmin'} =~ /0*(\d+)(\d{2})$/) {
1881
($starthour, $startmin)=($1, $2);
1882
($starthour, $startampm)=ow::datetime::hour24to12($starthour) if ($prefs{'hourformat'}==12);
1883
}
1884
1885
$temphtml = $lang_text{'calfmt_hourminampm'};
1886
$temphtml2 = popup_menu(-name=>'starthour',
1887
-values=>\@hourlist,
1888
-default=>$starthour,
1889
-labels=>\%numlabels,
1890
-override=>'1');
1891
$temphtml2 .= "<B>:</B>";
1892
$temphtml2 .= popup_menu(-name=>'startmin',
1893
-values=>[0,5,10,15,20,25,30,35,40,45,50,55],
1894
-default=>$startmin,
1895
-labels=>\%numlabels,
1896
-override=>'1');
1897
$temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
1898
if ($prefs{'hourformat'}==12) {
1899
$temphtml2 = popup_menu(-name=>'startampm',
1900
-values=>['am','pm'],
1901
-default=>$startampm,
1902
-labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
1903
-override=>'1');
1904
} else {
1905
$temphtml2 = '';
1906
}
1907
$temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
1908
$html =~ s/\@\@\@STARTHOURMINMENU\@\@\@/$temphtml/;
1909
1910
my ($endhour, $endmin, $endampm)=('none', 0, 'am');
1911
if ($items{$index}{'endhourmin'} =~ /0*(\d+)(\d{2})$/) {
1912
($endhour, $endmin)=($1, $2);
1913
($endhour, $endampm)=ow::datetime::hour24to12($endhour) if ($prefs{'hourformat'}==12);
1914
}
1915
1916
$temphtml = $lang_text{'calfmt_hourminampm'};
1917
$temphtml2 = popup_menu(-name=>'endhour',
1918
-values=>\@hourlist,
1919
-default=>$endhour,
1920
-labels=>\%numlabels,
1921
-override=>'1');
1922
$temphtml2 .= "<B>:</B>";
1923
$temphtml2 .= popup_menu(-name=>'endmin',
1924
-values=>[0,5,10,15,20,25,30,35,40,45,50,55],
1925
-default=>$endmin,
1926
-labels=>\%numlabels,
1927
-override=>'1');
1928
$temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
1929
if ($prefs{'hourformat'}==12) {
1930
$temphtml2 = popup_menu(-name=>'endampm',
1931
-values=>['am','pm'],
1932
-default=>$endampm,
1933
-labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
1934
-override=>'1');
1935
} else {
1936
$temphtml2 = '';
1937
}
1938
$temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
1939
$html =~ s/\@\@\@ENDHOURMINMENU\@\@\@/$temphtml/;
1940
1941
1942
# deconstruct the idate
1943
# An idate has the following format: <years><months><days><dayofweek>
1944
# An idate can look like:
1945
# 20030808 The event occurs on August 8, 2003, This Month, This Day only
1946
# (20030808|20030809) The event occurs on August 8 and 9, 2003 (or August 8 and Next 1 day)
1947
# .*,04,07,.* The event occurs on April 7, Every Year
1948
# .*,.*,((1[5-9])|(2[0-1])),Tue The event occurs on the 3rd Tuesday, Every Month, Every Year
1949
# 2003,.*,.*,Wed The event occurs Every Wednesday, Every Week of 2003
1950
# 2003,.*,11,.* The event occurs Every 11th day, Every Month of 2003
1951
my ($everyyear, $monthfreq, $dayfreq, $dow, $startdate, $enddate, $ndays) = '';
1952
1953
my $dayfreq_default = "thisdayonly";
1954
my $thisandnextndays_default = 0;
1955
my $ndays_default = "";
1956
my $monthfreq_default = "thismonthonly";
1957
my $everyyear_default = 0;
1958
my $linkstr_default=$items{$index}{'link'};
1959
my $emailstr_default=$items{$index}{'email'};
1960
1961
if ($items{$index}{'idate'}=~/,/) { #idate has recurrance in it
1962
($everyyear, $monthfreq, $dayfreq, $dow) = split(/,/, $items{$index}{'idate'});
1963
my %weekorder_day_wild_reversed = ( "0[1-7]" => 1,
1964
"((0[8-9])|(1[0-4]))" => 2,
1965
"((1[5-9])|(2[0-1]))" => 3,
1966
"2[2-8]" => 4);
1967
1968
if ($weekorder_day_wild_reversed{$dayfreq}) {
1969
$dayfreq_default = "thewdayofthismonth";
1970
} elsif ($dayfreq eq '.*') {
1971
$dayfreq_default = "everywdaythismonth";
1972
}
1973
if ($monthfreq eq '(01|03|05|07|09|11)') {
1974
$monthfreq_default = "everyoddmonththisyear";
1975
} elsif ($monthfreq eq '(02|04|06|08|10|12)') {
1976
$monthfreq_default = "everyevenmonththisyear"
1977
} elsif ($monthfreq eq '.*') {
1978
$monthfreq_default = "everymonththisyear";
1979
}
1980
if ($everyyear eq '.*') {
1981
$everyyear_default = 1;
1982
}
1983
} elsif ($items{$index}{'idate'}=~/^\(?(\d+)\|?.*?\|?(\d+)?\)?$/) {
1984
# That regex breaks apart idates like (20030808|20030809)
1985
$startdate = $1;
1986
$enddate = $2 || '';
1987
if ($enddate ne '') { # we have a next Nday recurrance here
1988
$thisandnextndays_default = 1;
1989
$ndays_default = $items{$index}{'idate'} =~ tr/|/|/; # count pipes - cheap and easy
1990
}
1991
} else {
1992
openwebmailerror(__FILE__, __LINE__, "Index $index idate $lang_err{'doesnt_exist'}");
1993
writelog("edit calitem error - idate wrong format, index=$index");
1994
writehistory("edit calitem error - idate wrong format, index=$index");
1995
}
1996
1997
my $t=ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
1998
my $wdaynum=(ow::datetime::seconds2array($t))[6];
1999
my $weekorder=int(($day+6)/7);
2000
my %dayfreqlabels = ('thisdayonly' =>$lang_text{'thisday_only'},
2001
'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
2002
'everywdaythismonth'=>$lang_text{'every_wday_thismonth'});
2003
$dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@ORDER\@\@\@/$lang_order{$weekorder}/;
2004
$dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum}/;
2005
$dayfreqlabels{'everywdaythismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum}/;
2006
2007
if ($weekorder<=4) {
2008
$temphtml = popup_menu(-name=>'dayfreq',
2009
-values=>['thisdayonly', 'thewdayofthismonth', 'everywdaythismonth'],
2010
-default=>$dayfreq_default,
2011
-labels=>\%dayfreqlabels,
2012
-override=>'1');
2013
} else {
2014
$temphtml = popup_menu(-name=>'dayfreq',
2015
-values=>['thisdayonly', 'everywdaythismonth'],
2016
-default=>$dayfreq_default,
2017
-labels=>\%dayfreqlabels,
2018
-override=>'1');
2019
}
2020
$html =~ s/\@\@\@FREQMENU\@\@\@/$temphtml/;
2021
2022
$temphtml = checkbox(-name=>'thisandnextndays',
2023
-value=>'1',
2024
-checked=>$thisandnextndays_default,
2025
-label=>'',
2026
-override=>'1');
2027
$html =~ s/\@\@\@THISANDNEXTNDAYSCHECKBOX\@\@\@/$temphtml/g;
2028
2029
$temphtml = textfield(-name=>'ndays',
2030
-default=>$ndays_default,
2031
-size=>'2',
2032
-override=>'1');
2033
$html =~ s/\@\@\@NDAYSFIELD\@\@\@/$temphtml/;
2034
2035
my %monthfreqlabels = ('thismonthonly' =>$lang_text{'thismonth_only'},
2036
'everyoddmonththisyear' =>$lang_text{'every_oddmonth_thisyear'},
2037
'everyevenmonththisyear'=>$lang_text{'every_evenmonth_thisyear'},
2038
'everymonththisyear' =>$lang_text{'every_month_thisyear'});
2039
my @monthfreq =('thismonthonly');
2040
if ($month%2==1) {
2041
push(@monthfreq, 'everyoddmonththisyear');
2042
} else {
2043
push(@monthfreq, 'everyevenmonththisyear');
2044
}
2045
push(@monthfreq, 'everymonththisyear');
2046
$temphtml = popup_menu(-name=>'monthfreq',
2047
-values=>\@monthfreq,
2048
-default=>$monthfreq_default,
2049
-labels=>\%monthfreqlabels,
2050
-override=>'1');
2051
$html =~ s/\@\@\@MONTHFREQMENU\@\@\@/$temphtml/g;
2052
2053
2054
$temphtml = checkbox(-name=>'everyyear',
2055
-value=>'1',
2056
-checked=>$everyyear_default,
2057
-label=>'',
2058
-override=>'1');
2059
$html =~ s/\@\@\@EVERYYEARCHECKBOX\@\@\@/$temphtml/g;
2060
2061
2062
$linkstr_default="http://" if ($linkstr_default eq "0");
2063
$temphtml = textfield(-name=>'link',
2064
-default=>$linkstr_default,
2065
-size=>'32',
2066
-override=>'1');
2067
$html =~ s/\@\@\@LINKFIELD\@\@\@/$temphtml/;
2068
2069
2070
$emailstr_default="" if ($emailstr_default eq "0");
2071
if ($config{'calendar_email_notifyinterval'} > 0 ) {
2072
templateblock_enable($html, 'EMAIL');
2073
$temphtml = textfield(-name=>'email',
2074
-default=>$emailstr_default,
2075
-size=>'32',
2076
-override=>'1');
2077
$html =~ s/\@\@\@EMAILFIELD\@\@\@/$temphtml/;
2078
} else {
2079
$temphtml = ow::tool::hiddens(email=>$emailstr_default);
2080
templateblock_disable($html, 'EMAIL', $temphtml);
2081
}
2082
2083
$temphtml = qq|<table><tr>|;
2084
$temphtml .= qq|<td>|;
2085
$temphtml .= popup_menu(-name=>'eventcolor',
2086
-values=>['none', sort keys %eventcolors],
2087
-default=>$items{$index}{'eventcolor'},
2088
-labels=>{ none=> $lang_text{'none'} },
2089
-override=>'1');
2090
$temphtml .= qq|</td>|;
2091
my $eventcolornum = 1;
2092
foreach (sort keys %eventcolors) {
2093
$temphtml .= qq|<td width="14" align="center" bgcolor="#$eventcolors{$_}">|.
2094
qq|<a href="#" onClick='javascript:document.editcalendar.eventcolor.selectedIndex="$eventcolornum"'>$_</a></td>\n|;
2095
$eventcolornum++;
2096
}
2097
$temphtml .= qq|<td width="14" align="center">|.
2098
qq|<a href="#" onClick='javascript:document.editcalendar.eventcolor.selectedIndex="0"'>--</a></td>\n|;
2099
2100
$temphtml .= qq|</tr></table>|;
2101
$html =~ s/\@\@\@EVENTCOLORMENU\@\@\@/$temphtml/;
2102
2103
$temphtml = submit("$lang_text{'save'}");
2104
$html =~ s/\@\@\@SUBMITBUTTON\@\@\@/$temphtml/;
2105
2106
$temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
2107
-name=>'cancelform',
2108
-override=>'1').
2109
ow::tool::hiddens(sessionid=>$thissession,
2110
folder=>$folder,
2111
message_id=>$messageid,
2112
year=>$year);
2113
if (defined(param('callist'))) {
2114
$temphtml .= ow::tool::hiddens(action=>'callist');
2115
} else {
2116
$temphtml .= ow::tool::hiddens(month=>$month,
2117
day=>$day,
2118
action=>'calday');
2119
}
2120
$html =~ s/\@\@\@STARTCANCELFORM\@\@\@/$temphtml/;
2121
2122
$temphtml = submit($lang_text{'cancel'});
2123
$html =~ s/\@\@\@CANCELBUTTON\@\@\@/$temphtml/;
2124
2125
$temphtml = end_form();
2126
$html =~ s/\@\@\@ENDFORM\@\@\@/$temphtml/g;
2127
2128
httpprint([], [htmlheader(), $html, htmlfooter(2)]);
2129
}
2130
########## END EDIT_ITEM #########################################
2131
2132
########## ADD_ITEM ##############################################
2133
# add an item to user calendar
2134
sub add_item {
2135
my ($year, $month, $day,
2136
$string,
2137
$starthour, $startmin, $startampm,
2138
$endhour, $endmin, $endampm,
2139
$dayfreq,
2140
$thisandnextndays, $ndays,
2141
$monthfreq,
2142
$everyyear,
2143
$link, $email, $eventcolor)=@_;
2144
my $line;
2145
return if ($string=~/^\s?$/);
2146
2147
# check for bad input that would kill our database format
2148
if ($string =~ /\@\@\@/) {
2149
openwebmailerror(__FILE__, __LINE__, "$lang_err{'pipe_char_not_allowed'}");
2150
}
2151
if ($link =~ /\@\@\@/) {
2152
openwebmailerror(__FILE__, __LINE__, "$lang_err{'pipe_char_not_allowed'}");
2153
}
2154
# check for bad input that would confuse our database format
2155
if ($string =~ /\@$/) {
2156
$string=$string." ";
2157
} elsif ($string =~ /^\@/) {
2158
$string=" ".$string;
2159
}
2160
if ($link =~ /\@$/) {
2161
$link=$link." ";
2162
} elsif ($link =~ /^\@/) {
2163
$link=" ".$link;
2164
}
2165
$link=~s/\Q$thissession\E/\%THISSESSION\%/;
2166
$link=0 if ($link !~ m!://[^\s]+!);
2167
$email=0 if ($email !~ m![^\[email protected]][email protected][^\[email protected]]+!);
2168
2169
# translate time format to military time.
2170
my $starthourmin=0;
2171
my $endhourmin=0;
2172
if ($starthour =~ /\d+/) {
2173
if ($prefs{'hourformat'}==12) {
2174
$starthour+=12 if ($startampm eq "pm" && $starthour< 12);
2175
$starthour=0 if ($startampm eq "am" && $starthour==12);
2176
}
2177
$starthourmin = sprintf("%02d%02d", $starthour,$startmin);
2178
}
2179
if ($endhour =~ /\d+/) {
2180
if ($prefs{'hourformat'}==12) {
2181
$endhour+=12 if ($endampm eq "pm" && $endhour< 12);
2182
$endhour=0 if ($endampm eq "am" && $endhour==12);
2183
}
2184
$endhourmin = sprintf("%02d%02d", $endhour,$endmin);
2185
}
2186
2187
# fix the day if needed
2188
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
2189
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
2190
$day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
2191
2192
my $calbookfile=dotpath('calendar.book');
2193
2194
my ($item_count, %items, %indexes);
2195
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
2196
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2197
}
2198
2199
my $index = $item_count+19690404; # avoid collision with old records
2200
my $t = ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
2201
my $dow = $ow::datetime::wday_en[(ow::datetime::seconds2array($t))[6]];
2202
2203
# construct the idate for this record.
2204
if ($dayfreq eq 'thisdayonly' && $monthfreq eq 'thismonthonly' && !$everyyear) {
2205
if ($thisandnextndays && $ndays) {
2206
if ($ndays !~ /\d+/) {
2207
openwebmailerror(__FILE__, __LINE__, "$lang_err{'badnum_in_days'}: $ndays");
2208
}
2209
my $date_wild='(';
2210
for (my $i=0; $i<=$ndays; $i++) {
2211
my ($y, $m, $d)=(ow::datetime::seconds2array($t+86400*$i))[5,4,3];
2212
$date_wild.='|' if ($i>0);
2213
$date_wild.=sprintf("%04d%02d%02d", $y+1900, $m+1, $d);
2214
}
2215
$date_wild.=')';
2216
$items{$index}{'idate'}=$date_wild;
2217
} else {
2218
$items{$index}{'idate'}=sprintf("%04d%02d%02d", $year, $month, $day);
2219
}
2220
2221
} elsif ($dayfreq eq 'thewdayofthismonth') {
2222
my $year_wild=sprintf("%04d", $year);
2223
my $month_wild=sprintf("%02d", $month);
2224
my $day_wild=sprintf("%02d", $day);
2225
2226
$year_wild = ".*" if ($everyyear);
2227
if ($monthfreq eq 'everyoddmonththisyear') {
2228
$month_wild="(01|03|05|07|09|11)";
2229
} elsif ($monthfreq eq 'everyevenmonththisyear') {
2230
$month_wild="(02|04|06|08|10|12)";
2231
} elsif ($monthfreq eq 'everymonththisyear') {
2232
$month_wild = ".*";
2233
}
2234
my %weekorder_day_wild= ( 1 => "0[1-7]",
2235
2 => "((0[8-9])|(1[0-4]))",
2236
3 => "((1[5-9])|(2[0-1]))",
2237
4 => "2[2-8]" );
2238
my $weekorder=int(($day+6)/7);
2239
$day_wild=$weekorder_day_wild{$weekorder} if ($weekorder_day_wild{$weekorder} ne "");
2240
2241
$items{$index}{'idate'}="$year_wild,$month_wild,$day_wild,$dow";
2242
2243
} else { # everywdaythismonth and else...
2244
my $year_wild=sprintf("%04d", $year);
2245
my $month_wild=sprintf("%02d", $month);
2246
2247
$year_wild = ".*" if ($everyyear);
2248
if ($monthfreq eq 'everyoddmonththisyear') {
2249
$month_wild="(01|03|05|07|09|11)";
2250
} elsif ($monthfreq eq 'everyevenmonththisyear') {
2251
$month_wild="(02|04|06|08|10|12)";
2252
} elsif ($monthfreq eq 'everymonththisyear') {
2253
$month_wild = ".*";
2254
}
2255
2256
if ($dayfreq eq 'everywdaythismonth') {
2257
$items{$index}{'idate'}="$year_wild,$month_wild,.*,$dow";
2258
} else {
2259
my $daystr=sprintf("%02d", $day);
2260
$items{$index}{'idate'}="$year_wild,$month_wild,$daystr,.*";
2261
}
2262
}
2263
2264
$items{$index}{'starthourmin'}="$starthourmin"; # " is required or "0000" will be treated as 0?
2265
$items{$index}{'endhourmin'}="$endhourmin";
2266
$items{$index}{'string'}=$string;
2267
$items{$index}{'link'}=$link;
2268
$items{$index}{'email'}=$email;
2269
$items{$index}{'eventcolor'}=$eventcolor;
2270
2271
if (writecalbook($calbookfile, \%items) <0 ) {
2272
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2273
}
2274
2275
reset_notifycheck_for_newitem($items{$index});
2276
2277
my $msg="add calitem - index=$index, start=$starthourmin, end=$endhourmin, str=$string";
2278
writelog($msg);
2279
writehistory($msg);
2280
}
2281
########## END ADD_ITEM ##########################################
2282
2283
########## DEL_ITEM ##############################################
2284
# delete an item from user calendar
2285
sub del_item {
2286
my $index=$_[0];
2287
2288
my $calbookfile=dotpath('calendar.book');
2289
my (%items, %indexes);
2290
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
2291
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2292
}
2293
return if (! defined($items{$index}) );
2294
2295
delete $items{$index};
2296
if ( writecalbook($calbookfile, \%items) <0 ) {
2297
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2298
}
2299
2300
my $msg="delete calitem - index=$index, t=$items{$index}{'starthourmin'}, str=$items{$index}{'string'}";
2301
writelog($msg);
2302
writehistory($msg);
2303
}
2304
########## END DEL_ITEM ##########################################
2305
2306
########## UPDATE_ITEM ###########################################
2307
# update an item in user calendar
2308
sub update_item {
2309
my ($index,
2310
$year, $month, $day,
2311
$string,
2312
$starthour, $startmin, $startampm,
2313
$endhour, $endmin, $endampm,
2314
$dayfreq,
2315
$thisandnextndays, $ndays, $monthfreq, $everyyear,
2316
$link, $email, $eventcolor)=@_;
2317
my $line;
2318
2319
return if ($string=~/^\s?$/);
2320
2321
# check for valid input
2322
if ($string =~ /\@{3}/) {
2323
openwebmailerror(__FILE__, __LINE__, "$lang_err{'at_char_not_allowed'}");
2324
}
2325
if ($link =~ /\@{3}/) {
2326
openwebmailerror(__FILE__, __LINE__, "$lang_err{'at_char_not_allowed'}");
2327
}
2328
# check for bad input that would confuse our database format
2329
if ($string =~ /\@$/) {
2330
$string=$string." ";
2331
} elsif ($string =~ /^\@/) {
2332
$string=" ".$string;
2333
}
2334
if ($link =~ /\@$/) {
2335
$link=$link." ";
2336
} elsif ($link =~ /^\@/) {
2337
$link=" ".$link;
2338
}
2339
$link=~s/\Q$thissession\E/\%THISSESSION\%/;
2340
$link=0 if ($link !~ m!://[^\s]+!);
2341
$email=0 if ($email !~ m![^\[email protected]][email protected][^\[email protected]]+!);
2342
2343
# translate time format to military time.
2344
my $starthourmin=0;
2345
my $endhourmin=0;
2346
if ($starthour =~ /\d+/) {
2347
if ($prefs{'hourformat'}==12) {
2348
$starthour+=12 if ($startampm eq "pm" && $starthour< 12);
2349
$starthour=0 if ($startampm eq "am" && $starthour==12);
2350
}
2351
$starthourmin = sprintf("%02d%02d", $starthour,$startmin);
2352
}
2353
if ($endhour =~ /\d+/) {
2354
if ($prefs{'hourformat'}==12) {
2355
$endhour+=12 if ($endampm eq "pm" && $endhour< 12);
2356
$endhour=0 if ($endampm eq "am" && $endhour==12);
2357
}
2358
$endhourmin = sprintf("%02d%02d", $endhour,$endmin);
2359
}
2360
2361
# fix the day if needed
2362
my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
2363
$days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
2364
$day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
2365
2366
my $t = ow::datetime::array2seconds(1,1,1, $day,$month-1,$year-1900);
2367
my $dow = $ow::datetime::wday_en[(ow::datetime::seconds2array($t))[6]];
2368
2369
# construct the idate for this record.
2370
my $idate = '';
2371
if ($dayfreq eq 'thisdayonly' && $monthfreq eq 'thismonthonly' && !$everyyear) {
2372
if ($thisandnextndays && $ndays) {
2373
if ($ndays !~ /\d+/) {
2374
openwebmailerror(__FILE__, __LINE__, "$lang_err{'badnum_in_days'}: $ndays");
2375
}
2376
my $date_wild='(';
2377
for (my $i=0; $i<=$ndays; $i++) {
2378
my ($y, $m, $d)=(ow::datetime::seconds2array($t+86400*$i))[5,4,3];
2379
$date_wild.='|' if ($i>0);
2380
$date_wild.=sprintf("%04d%02d%02d", $y+1900, $m+1, $d);
2381
}
2382
$date_wild.=')';
2383
$idate=$date_wild;
2384
} else {
2385
$idate=sprintf("%04d%02d%02d", $year, $month, $day);
2386
}
2387
2388
} elsif ($dayfreq eq 'thewdayofthismonth') {
2389
my $year_wild=sprintf("%04d", $year);
2390
my $month_wild=sprintf("%02d", $month);
2391
my $day_wild=sprintf("%02d", $day);
2392
2393
$year_wild = ".*" if ($everyyear);
2394
if ($monthfreq eq 'everyoddmonththisyear') {
2395
$month_wild="(01|03|05|07|09|11)";
2396
} elsif ($monthfreq eq 'everyevenmonththisyear') {
2397
$month_wild="(02|04|06|08|10|12)";
2398
} elsif ($monthfreq eq 'everymonththisyear') {
2399
$month_wild = ".*";
2400
}
2401
my %weekorder_day_wild= ( 1 => "0[1-7]",
2402
2 => "((0[8-9])|(1[0-4]))",
2403
3 => "((1[5-9])|(2[0-1]))",
2404
4 => "2[2-8]" );
2405
my $weekorder=int(($day+6)/7);
2406
$day_wild=$weekorder_day_wild{$weekorder} if ($weekorder_day_wild{$weekorder} ne "");
2407
2408
$idate="$year_wild,$month_wild,$day_wild,$dow";
2409
2410
} else { # everywdaythismonth and else...
2411
my $year_wild=sprintf("%04d", $year);
2412
my $month_wild=sprintf("%02d", $month);
2413
2414
$year_wild = ".*" if ($everyyear);
2415
if ($monthfreq eq 'everyoddmonththisyear') {
2416
$month_wild="(01|03|05|07|09|11)";
2417
} elsif ($monthfreq eq 'everyevenmonththisyear') {
2418
$month_wild="(02|04|06|08|10|12)";
2419
} elsif ($monthfreq eq 'everymonththisyear') {
2420
$month_wild = ".*";
2421
}
2422
2423
if ($dayfreq eq 'everywdaythismonth') {
2424
$idate="$year_wild,$month_wild,.*,$dow";
2425
} else {
2426
my $daystr=sprintf("%02d", $day);
2427
$idate="$year_wild,$month_wild,$daystr,.*";
2428
}
2429
}
2430
2431
my $calbookfile=dotpath('calendar.book');
2432
2433
my (%items, %indexes);
2434
if ( readcalbook($calbookfile, \%items, \%indexes, 0)<0 ) {
2435
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2436
}
2437
if (! defined($items{$index}) ) {
2438
openwebmailerror(__FILE__, __LINE__, "$lang_text{'calendar'} $index $lang_err{'doesnt_exist'}");
2439
writelog("update calitem error - item missing, index=$index");
2440
writehistory("update calitem error - item missing, index=$index");
2441
}
2442
2443
$items{$index}{'starthourmin'}="$starthourmin"; # " is required or "0000" will be treated as 0?
2444
$items{$index}{'endhourmin'}="$endhourmin";
2445
$items{$index}{'idate'}="$idate";
2446
$items{$index}{'string'}=$string;
2447
$items{$index}{'link'}=$link;
2448
$items{$index}{'email'}=$email;
2449
$items{$index}{'eventcolor'}="$eventcolor";
2450
2451
if ( writecalbook($calbookfile, \%items) <0 ) {
2452
openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $calbookfile");
2453
}
2454
2455
reset_notifycheck_for_newitem($items{$index});
2456
2457
my $msg="update calitem - index=$index, start=$starthourmin, end=$endhourmin, str=$string";
2458
writelog($msg);
2459
writehistory($msg);
2460
}
2461
########## END UPDATE_ITEM #######################################
2462
2463
########## SET_DAYS_IN_MONTH #####################################
2464
# set the day number of each cell in the month calendar
2465
sub set_days_in_month {
2466
my ($year, $month, $days_in_month) = @_;
2467
2468
my %wdaynum=qw(Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6);
2469
foreach (keys %wdaynum) {
2470
$wdaynum{$_}=($wdaynum{$_}+7-$prefs{'calendar_weekstart'})%7;
2471
}
2472
my $time = ow::datetime::array2seconds(0,0,12, 1,$month-1,$year-1900);
2473
my $weekday = ow::datetime::seconds2array($time); $weekday =~ s/^(\w+).*$/$1/;
2474
2475
my @days;
2476
my $day_counter = 1;
2477
for my $x (0..5) {
2478
for my $y (0..6) {
2479
if ( ($x>0 || $y>=$wdaynum{$weekday}) &&
2480
$day_counter<=$days_in_month ) {
2481
$days[$x][$y] = $day_counter;
2482
$day_counter++;
2483
}
2484
}
2485
}
2486
return @days;
2487
}
2488
########## END SET_DAYS_IN_MONTH #################################
2489
2490
########## HOURMIN2STR ###########################################
2491
# convert military time (eg:1700) to timestr (eg:05:00 pm)
2492
sub hourmin2str {
2493
my ($hourmin, $hourformat) = @_;
2494
if ($hourmin =~ /(\d+)(\d{2})$/) {
2495
my ($hour, $min) = ($1, $2);
2496
$hour =~ s/^0(.+)/$1/;
2497
if ($hourformat==12) {
2498
my $ampm;
2499
($hour, $ampm)=ow::datetime::hour24to12($hour);
2500
$hourmin = $lang_text{'calfmt_hourminampm'};
2501
$hourmin =~ s/\@\@\@HOURMIN\@\@\@/$hour:$min/;
2502
$hourmin =~ s/\@\@\@AMPM\@\@\@/$lang_text{$ampm}/;
2503
} else {
2504
$hourmin = sprintf("%02d", $hour) . ":" . sprintf("%02d", $min);
2505
}
2506
}
2507
return $hourmin;
2508
}
2509
########## END HOURMIN2STR #######################################
2510
2511
########## FORMATTED_DATE ########################################
2512
# convert date to language dependent str based on the format
2513
sub