--- loncom/interface/lonannounce.pm 2006/01/12 23:00:08 1.41 +++ loncom/interface/lonannounce.pm 2013/05/25 21:45:42 1.86 @@ -1,7 +1,7 @@ # The LearningOnline Network # Announce # -# $Id: lonannounce.pm,v 1.41 2006/01/12 23:00:08 albertel Exp $ +# $Id: lonannounce.pm,v 1.86 2013/05/25 21:45:42 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,15 +33,19 @@ use Apache::Constants qw(:common); use Apache::loncommon; use Apache::lonhtmlcommon(); use Apache::lonlocal; +use Apache::lonnavmaps(); use Apache::lonrss(); use Apache::lonnet; use HTML::Entities(); +use LONCAPA qw(:match); +use DateTime; +use DateTime::TimeZone; my %todayhash; my %showedcheck; sub editfield { - my ($r,$start,$end,$text)=@_; + my ($r,$start,$end,$text,$crstype)=@_; # Deal with date forms my $startdateform = &Apache::lonhtmlcommon::date_setter('anno', 'startdate', @@ -49,22 +53,29 @@ sub editfield { my $enddateform = &Apache::lonhtmlcommon::date_setter('anno', 'enddate', $end); - my $help=&Apache::loncommon::help_open_menu('','Calendar Add Announcement','Calendar_Add_Announcement','',274,'Communication Tools'); - my %lt=&Apache::lonlocal::texthash('post' => 'Post Announcement', + #my $help=&Apache::loncommon::help_open_menu('Calendar Add Announcement','Calendar_Add_Announcement',274,'Communication Tools'); + my $help=&Apache::loncommon::help_open_topic('Calendar_Add_Announcement'); + + my %lt=&Apache::lonlocal::texthash('annon' => 'Course Announcements', + 'post' => 'Post Announcement', 'start' => 'Starting date', 'end' => 'Ending date', 'incrss' => 'Include in course RSS newsfeed'); + if ($crstype eq 'Community') { + $lt{'annon'} = &mt('Community Announcements'); + $lt{'incrss'} = &mt('Include in community RSS newsfeed'); + } $r->print(< +

$lt{'annon'} $help

+
$lt{'start'}:$startdateform
$lt{'end'}:$enddateform

- -

+ +

ENDFORM } @@ -72,91 +83,145 @@ sub readcalendar { my $courseid=shift; my $coursenum=$env{'course.'.$courseid.'.num'}; my $coursedom=$env{'course.'.$courseid.'.domain'}; + if ($coursenum eq '' || $coursedom eq '') { + my %courseinfo=&Apache::lonnet::coursedescription($courseid); + if ($coursenum eq '' && exists($courseinfo{'num'})) { + $coursenum = $courseinfo{'num'}; + } + if ($coursedom eq '' && exists($courseinfo{'domain'})) { + $coursedom = $courseinfo{'domain'}; + } + } + my %thiscal=&Apache::lonnet::dump('calendar',$coursedom,$coursenum); my %returnhash=(); - foreach (keys %thiscal) { - unless (($_=~/^error\:/) || ($thiscal{$_}=~/^error\:/)) { - $returnhash{$courseid.'@'.$_}=$thiscal{$_}; + foreach my $item (keys(%thiscal)) { + unless (($item=~/^error\:/) || ($thiscal{$item}=~/^error\:/)) { + my ($start,$end)=split('_',$item); + $returnhash{join("\0",$courseid,$start,$end)}=$thiscal{$item}; } } + my $can_see_hidden = ($env{'request.role.adv'} && + ($courseid eq $env{'request.course.id'})); + + my $navmap; if ($courseid eq $env{'request.course.id'}) { - my %resourcedata= - &Apache::lonnet::dump('resourcedata',$coursedom,$coursenum); - foreach my $thiskey (sort keys %resourcedata) { - if ($resourcedata{$thiskey.'.type'}=~/^date/) { - my ($course,$middle,$part,$name)= - ($thiskey=~/^(\w+)\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/); - my $section=&mt('All Students'); - if ($middle=~/^\[(.*)\]\./) { - my $sec=$1; - # if we have a section don't show ones that aren't ours - if ($env{'request.course.sec'} && - $env{'request.course.sec'} ne $sec) { next; } - # if a student without a section don't show any section ones - if (!$env{'request.role.adv'} && - !$env{'request.course.sec'}) { next; } - $section=&mt('Group/Section').': '.$1; - $middle=~s/^\[(.*)\]\.//; + $navmap = Apache::lonnavmaps::navmap->new(); + } + + my $resourcedata= + &Apache::lonnet::get_courseresdata($coursenum,$coursedom); + if (ref($resourcedata) ne 'HASH') { + return %returnhash; + } + foreach my $thiskey (keys(%$resourcedata)) { + if ($resourcedata->{$thiskey.'.type'}=~/^date/) { + my ($course,$middle,$part,$name)= + ($thiskey=~/^(\Q$courseid\E)\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/); + + my %data = ( 'section' => &mt('All Students')); + if ($middle=~/^\[(.*)\]\./) { + my $sec=$1; + # if we have a section don't show ones that aren't ours + if ($env{'request.course.sec'} && + $env{'request.course.sec'} ne $sec) { next; } + # if a student without a section don't show any section ones + if (!$env{'request.role.adv'} && + !$env{'request.course.sec'}) { next; } + $data{'section'}=&mt('Group/Section').': '.$1; + $middle=~s/^\[(.*)\]\.//; + } + $middle=~s/\.$//; + $data{'realm'}=&mt('All Resources'); + if ($middle eq '___(all)') { + if (!$can_see_hidden && !$navmap) { + next; } - $middle=~s/\.$//; - my $realm=&mt('All Resources'); - if ($middle=~/^(.+)\_\_\_\(all\)$/) { - $realm=&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1); - } elsif ($middle) { - $realm=&mt('Resource').': '.&Apache::lonnet::gettitle($middle); + } elsif ($middle=~/^(.+)\_\_\_\(all\)$/) { + my $map_url=$1; + if (!$can_see_hidden && !$navmap) { + next; } - my $datetype=''; - if ($name eq 'duedate') { - $datetype=&mt('Due'); -# see if accidentally answerdate is before duedate - my $answerkey=$thiskey; - $answerkey=~s/duedate$/answerdate/; - if ($resourcedata{$thiskey}>$resourcedata{$answerkey}) { - $datetype='Due and Answer Available'; + if (!$can_see_hidden) { + my $res = $navmap->getResourceByUrl($map_url); + if ($res && $res->randomout()) { + next; } } - if ($name eq 'opendate') { $datetype=&mt('Opening'); } - if ($name eq 'answerdate') { -# see if accidentally answerdate is before duedate - my $duekey=$thiskey; - $duekey=~s/answerdate$/duedate/; - if ($resourcedata{$duekey}>$resourcedata{$thiskey}) { -# forget it + $data{'realm'}=&mt('Folder/Map'); + $data{'url'} = $map_url; + } elsif ($middle) { + if (!$can_see_hidden && !$navmap) { + next; + } + if (!$can_see_hidden) { + my $res = $navmap->getBySymb($middle); + if ($res && $res->randomout()) { next; - } - $datetype=&mt('Answer Available'); + } + } + $data{'realm'} = &mt('Resource'); + $data{'symb'} = $middle; + } + $data{'datetype'} = $name; + if ($name eq 'duedate') { + $data{'datetype'} = &mt('Due'); +# see if accidentally answerdate is before duedate + my $answerkey=$thiskey; + $answerkey=~s/duedate$/answerdate/; + if ($resourcedata->{$thiskey}>$resourcedata->{$answerkey}) { + $data{'datetype'} = &mt('Due and Answer Available'); } - $returnhash{$courseid.'@'.$resourcedata{$thiskey}.'_'. - $resourcedata{$thiskey}}= - 'INTERNAL:'.$datetype.': '.$realm.' ('.$section.')'; } + if ($name eq 'opendate' + || $name eq 'contentopen' ) { + $data{'datetype'}=&mt('Opening'); + } + if ($name eq 'contentclose') { + $data{'datetype'}=&mt('Closing'); + } + if ($name eq 'answerdate') { +# see if accidentally answerdate is before duedate + my $duekey=$thiskey; + $duekey=~s/answerdate$/duedate/; + if ($resourcedata->{$duekey}>$resourcedata->{$thiskey}) { +# forget it + next; + } + $data{'datetype'}=&mt('Answer Available'); + } + $returnhash{join("\0",$courseid, + $resourcedata->{$thiskey}, + $resourcedata->{$thiskey})}=\%data; } } return %returnhash; } sub emptycell { - return ' '; + return ' '; } sub normalcell { - my ($day,$month,$year,$text)=@_; - my $output=''; - my @items=&order($text); + my ($day,$month,$year,$items_ref)=@_; + my $output; + my @items=&order($items_ref); foreach my $item (@items) { if ($item) { - my $internalflag=0; - my ($courseid,$start,$end,$msg)=split(/\@/,$item,4); - if ($msg=~/INTERNAL\:/) { - $msg=~s/INTERNAL\://gs; - $internalflag=1; - } + my ($courseid,$start,$end,$msg)=@$item; + my $internalflag= (ref($msg)) ? 1 : 0; + $msg = &display_msg($msg); my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}. '\n'.&Apache::lonlocal::locallocaltime($start); if ($start!=$end) { $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end); } $fullmsg.=':\n'.$msg; + $fullmsg=~s/[\n\r]/\\n/gs; + $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\''); + $fullmsg=~s/&/\\&/g; + my $short_msg = substr($msg,0,20).((length($msg) > 20)?'...':''); + if (defined($output)) { $output.='
'; } if ($courseid eq $env{'request.course.id'}) { if ((&Apache::lonnet::allowed('srm',$env{'request.course.id'})) && (!$showedcheck{$start.'_'.$end}) @@ -167,59 +232,56 @@ sub normalcell { $showedcheck{$start.'_'.$end}=1; } } - $fullmsg=~s/[\n\r]/\\n/gs; - $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\''); - $fullmsg=~s/&/\\&/g; $output.=''. - substr($msg,0,20).'...
'; + $short_msg.''; } } - return ''.&tfont(''.&picklink($day,$day,$month,$year).'
'.$output).''; + ($year eq $todayhash{'year'}))?'_current':''). + '" >'.&picklink($day,$day,$month,$year).'
'.$output.''; } sub plaincell { - my ($text)=@_; - my $output=''; - my @items=&order($text); + my ($items_ref)=@_; + my $output; + my @items=&order($items_ref); foreach my $item (@items) { - if ($item) { - my ($courseid,$start,$end,$msg)=split(/\@/,$item,4); + if (ref($item)) { + my ($courseid,$start,$end,$msg)=@$item; my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}. '\n'.&Apache::lonlocal::locallocaltime($start); if ($start!=$end) { $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end); } - $msg=~s/INTERNAL\://gs; + $msg = &display_msg($msg); $fullmsg.=':\n'.$msg; $fullmsg=~s/[\n\r]/\\n/gs; $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\''); $fullmsg=~s/&/\\&/g; + my $short_msg = substr($msg,0,80).((length($msg) > 80)?'...':''); + if (defined($output)) { $output.='
'; } $output.=''. - substr($msg,0,80).'...
'; + $short_msg.''; } } return $output; } sub listcell { - my ($text)=@_; + my ($items_ref)=@_; my $output=''; - my @items=&order($text); + my @items=&order($items_ref); foreach my $item (@items) { - if ($item) { - my ($courseid,$start,$end,$msg)=split(/\@/,$item,4); - $msg=~s/INTERNAL\://gs; - my $fullmsg=&Apache::lonlocal::locallocaltime($start); + if (ref($item)) { + my ($courseid,$start,$end,$msg)=@$item; + my $fullmsg=&Apache::lonlocal::locallocaltime($start); if ($start!=$end) { $fullmsg.=&mt(' to '). &Apache::lonlocal::locallocaltime($end); } - $fullmsg.=':
'. - $msg.''; + $fullmsg.=':
'.&display_msg($msg).''; $output.='
  • '.$fullmsg.'
  • '; } } @@ -227,64 +289,124 @@ sub listcell { } sub order { - my ($text)=@_; - my @items = split(/___&&&___/,$text); - sort { - my (undef,$astart,$aend)=split(/\@/,$a); - my (undef,$bstart,$bend)=split(/\@/,$b); + my ($items)=@_; + return sort { + my ($astart,$aend)=$a->[1,2]; + my ($bstart,$bend)=$b->[1,2]; if ($astart != $bstart) { return $astart <=> $bstart; } return $aend <=> $bend; - } @items; + } @$items; } sub nextday { - my %th=@_; - $th{'day'}++; + my ($tk,%th)=@_; + my ($incmonth,$incyear); + if ($th{'day'} > 27) { + if ($th{'month'} == 2) { + if ($th{'day'} == 29) { + $incmonth = 1; + } elsif ($th{'day'} == 28) { + if (!&is_leap_year($tk)) { + $incmonth = 1; + } + } + } elsif (($th{'month'} == 4) || ($th{'month'} == 6) || + ($th{'month'} == 9) || ($th{'month'} == 11)) { + if ($th{'day'} == 30) { + $incmonth = 1; + } + } elsif ($th{'day'} == 31) { + if ($th{'month'} == 12) { + $incyear = 1; + } else { + $incmonth = 1; + } + } + if ($incyear) { + $th{'day'} = 1; + $th{'month'} = 1; + $th{'year'}++; + } elsif ($incmonth) { + $th{'day'} = 1; + $th{'month'}++; + } else { + $th{'day'}++; + } + } else { + $th{'day'}++; + } return (&Apache::loncommon::maketime(%th),$th{'month'}); } +sub is_leap_year { + my ($thistime) = @_; + my ($is_leap,$timezone,$dt); + $timezone = &Apache::lonlocal::gettimezone(); + eval { + $dt = DateTime->from_epoch(epoch => $thistime) + ->set_time_zone($timezone); + }; + if (!$@) { + $is_leap = $dt->is_leap_year; + } + return $is_leap; +} + +sub display_msg { + my ($msg) = @_; + + # if it's not a ref, it's an instructor provided message + return $msg if (!ref($msg)); + + my $output = $msg->{'datetype'}. ': '.$msg->{'realm'}; + if (exists($msg->{'url'})) { + my $displayurl=&Apache::lonnet::gettitle($msg->{'url'}); + if ($msg->{'url'}!~/\Q$displayurl\E$/) { + $output .= ' - '.$displayurl; + } + } + if (exists($msg->{'symb'})) { + my $displaysymb=&Apache::lonnet::gettitle($msg->{'symb'}); + if ($msg->{'symb'}!~/\Q$displaysymb\E$/) { + $output .= ' - '.$displaysymb; + } + } + $output .= ' ('.$msg->{'section'}.') '; + return $output; +} + sub showday { my ($tk,$mode,%allcal)=@_; my %th=&Apache::loncommon::timehash($tk); - my ($nextday,$nextmonth)=&nextday(%th); - my $outp=''; + my ($nextday,$nextmonth)=&nextday($tk,%th); + my @outp; if ($mode) { my $oneday=24*3600; $tk-=$oneday; $nextday+=$oneday; } foreach my $item (keys(%allcal)) { - my ($course,$startdate,$enddate)=($item=~/^(\w+)\@(\d+)\_(\d+)$/); - if (($startdate<$nextday) && ($enddate>=$tk)) { - $outp.='___&&&___'.$course.'@'.$startdate.'@'.$enddate.'@'. - $allcal{$item}; + my ($courseid,$startdate,$enddate)= split("\0",$item); + if (($startdate<$nextday) && ($enddate>=$tk)) { + push(@outp,[$courseid,$startdate,$enddate,$allcal{$item}]); } } unless ($mode) { return ($nextday,$nextmonth,&normalcell( - $th{'day'},$th{'month'},$th{'year'},$outp)); - } elsif ($outp) { + $th{'day'},$th{'month'},$th{'year'},\@outp)); + } elsif (@outp) { if ($mode==1) { - return '
    '.&plaincell($outp); + return '
    '.&plaincell(\@outp); } else { - return ''; + return ''; } } else { return ''; } } -sub tfont { - my $text=shift; - if ($env{'form.pickdate'} eq 'yes') { - return ''.$text.''; - } else { - return $text; - } -} - sub picklink { my ($text,$day,$month,$year)=@_; if ($env{'form.pickdate'} eq 'yes') { @@ -297,7 +419,8 @@ sub picklink { sub dialscript { return (< + ENDDIA } +# ----------------------------------------------------- Summarize all calendars +sub get_all_calendars { + my %allcal=(); + my %courses = &Apache::loncommon::findallcourses(); + foreach my $course (sort(keys(%courses))) { + %allcal=(%allcal,&readcalendar($course)); + } + return %allcal; +} + +sub output_ics_file { + my ($r)=@_; +# RFC 2445 wants CRLF + my $crlf="\015\012"; +# Header + $r->print("BEGIN:VCALENDAR$crlf"); + $r->print("VERSION:2.0$crlf"); + $r->print("PRODID:-//LONCAPA//LONCAPA Calendar Output//EN$crlf"); + my %allcal=&get_all_calendars(); + foreach my $event (keys(%allcal)) { + my ($courseid,$startdate,$enddate)= split('\0',$event); + my $uid=$event; + $uid=~s/[\W\_]/-/gs; + $uid.='@loncapa'; + my $summary=&display_msg($allcal{$event}); + $summary=~s/\s+/ /gs; + $summary=$env{'course.'.$courseid.'.description'}.': '.$summary; + $r->print("BEGIN:VEVENT$crlf"); + $r->print("DTSTART:".&Apache::loncommon::utc_string($startdate).$crlf); + $r->print("DTEND:".&Apache::loncommon::utc_string($enddate).$crlf); + $r->print("SUMMARY:$summary$crlf"); + $r->print("UID:$uid$crlf"); + $r->print("END:VEVENT$crlf"); + } +# Footer + $r->print("END:VCALENDAR$crlf"); +} + +sub show_timezone { + my $tzone = &Apache::lonlocal::gettimezone(); + my $dt = DateTime->now(); + my $tz = DateTime::TimeZone->new( name => $tzone ); + return &mt('([_1] time zone)',$tz->short_name_for_datetime($dt)); +} sub handler { my $r = shift; + if ($r->uri=~/\.(ics|ical)$/) { + &Apache::loncommon::content_type($r,'text/calendar'); + &output_ics_file($r); + return OK; + } &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; @@ -323,8 +496,7 @@ sub handler { my $today=time; %todayhash=&Apache::loncommon::timehash($today); # ----------------------------------------------------------------- Check marks - %showedcheck=(); - undef %showedcheck; + undef(%showedcheck); # ---------------------------------------------------------- Get month and year &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['month','year','pickdate','formname','element']); @@ -336,23 +508,23 @@ sub handler { # ---------------------------------------------- See if we are in pickdate mode my $pickdatemode=($env{'form.pickdate'} eq 'yes'); - my $pickinfo='&pickdate=yes&formname='.$env{'form.formname'}. - '&element='.$env{'form.element'}; + my $pickinfo='&pickdate=yes&formname='.$env{'form.formname'}. + '&element='.$env{'form.element'}; # --------------------------------------------- Find out first day of the month - my %firstday=&Apache::loncommon::timehash( - &Apache::loncommon::maketime( 'day' => 1, 'month'=> $month, - 'year' => $year, 'hours' => 0, - 'minutes' => 0, 'seconds' => 0, - 'dlsav' => -1 )); + my $tk = &Apache::loncommon::maketime( 'day' => 1, + 'month'=> $month, + 'year' => $year, + 'hour' => 0, + 'minute' => 0, + 'second' => 0); + my %firstday = &Apache::loncommon::timehash($tk); my $weekday=$firstday{'weekday'}; + # ------------------------------------------------------------ Print the screen - my $html=&Apache::lonxml::xmlbegin(); - $r->print(< -The LearningOnline Network with CAPA - - ENDDOCUMENT + if ($pickdatemode) { # no big header in pickdate mode - $r->print(&Apache::loncommon::bodytag("Pick a Date",'','',1). + $r->print(&Apache::loncommon::start_page("Pick a Date",$js, + {'only_body' => 1,}). &dialscript(). ''); } else { - $r->print(&Apache::loncommon::bodytag("Announcements and Calendar")); + my $brcrum = [{href=>"/adm/announcements",text=>"Announcements and Calendar"}]; + $r->print(&Apache::loncommon::start_page("Communication",$js,{'bread_crumbs' => $brcrum})); } # does this user have privileges to post, etc? my $allowed=0; @@ -394,38 +569,55 @@ ENDDOCUMENT } # ------------------------------------------------------------ Process commands if ($serverpost) { - if ($env{'form.serveraction'}) { - foreach (keys %env) { - if ($_=~/^form\.postto\_(\w+)/) { - $r->print( - '
    Posting '.$1.': '.&Apache::lonnet::postannounce - ($1,$env{'form.serverannnounce'})); - } - } - } - $r->print(< -

    Post Server Announcements

    -Post announcements to the system login and roles screen
    -(leave blank to delete announcement)
    -
    -Check machines:
    -SERVERANNOUNCE + if ($env{'form.serveraction'}) { + my $rc; + my $message; + foreach my $key (keys(%env)) { + if ($key=~/^form\.postto\_(\w+[\w\-]*)/) { + $rc = &Apache::lonnet::postannounce + ($1,$env{'form.serverannnounce'}); + if ($rc eq 'ok') { + $message .= + &Apache::lonhtmlcommon::confirm_success( + &mt('Announcement posted to [_1]',$1)) + .'
    '; + } else { + $message .= + &Apache::lonhtmlcommon::confirm_success( + &mt('Posting announcement to [_1] failed: [_2]' + ,$1,$rc), 1) + .'
    '; + } + } + } + $r->print(&Apache::loncommon::confirmwrapper($message)); + } + $r->print('' + .'

    '.&mt('Post Server Announcements').'

    ' + .&mt('Post announcements to the system login and roles screen').'
    ' + .''.&mt('(leave blank to delete announcement)').'
    ' + .'
    ' + .&mt('Check machines:').'
    ' + ); # list servers - foreach (sort keys %Apache::lonnet::hostname) { - if (&Apache::lonnet::allowed('psa',$Apache::lonnet::hostdom{$_})) { - $r->print ('
    '. - $_.' '.$Apache::lonnet::hostname{$_}.' '. - 'current'); + my %hostname = &Apache::lonnet::all_hostnames(); + foreach my $host (sort(keys(%hostname))) { + if (&Apache::lonnet::allowed('psa', + &Apache::lonnet::host_domain($host))) { + $r->print (''. + &mt('Current Announcement').'
    '); } } $r->print( - '

    '); + '

    '); } if ($allowed) { my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my $crstype = &Apache::loncommon::course_type(); # ----------------------------------------------------- Store new submitted one if ($env{'form.action'} eq 'new') { my $startdate = @@ -443,7 +635,13 @@ SERVERANNOUNCE $startdate.'_'.$enddate => $env{'form.msg'} },$coursedom,$coursenum); if ($env{'form.rsspost'}) { - &Apache::lonrss::addentry($coursenum,$coursedom,'Course_Announcements', + my $feed; + if ($crstype eq 'Community') { + $feed = 'Community_Announcements'; + } else { + $feed = 'Course_Announcements'; + } + &Apache::lonrss::addentry($coursenum,$coursedom,$feed, &mt('Event from [_1] to [_2]', &Apache::lonlocal::locallocaltime($startdate), &Apache::lonlocal::locallocaltime($enddate)), @@ -453,8 +651,8 @@ SERVERANNOUNCE # ---------------------------------------------------------------- Remove items if ($env{'form.action'} eq 'del') { my @delwhich=(); - foreach (keys %env) { - if ($_=~/^form\.remove\_(.+)$/) { + foreach my $key (keys(%env)) { + if ($key=~/^form\.remove\_(.+)$/) { push(@delwhich,$1); } } @@ -465,96 +663,131 @@ SERVERANNOUNCE $tomorrowhash{'day'}++; my $tomorrow=&Apache::loncommon::maketime(%tomorrowhash); - &editfield($r,$today,$tomorrow,''); + &editfield($r,$today,$tomorrow,'',$crstype); } # ----------------------------------------------------- Summarize all calendars - my %allcal=(); - foreach (&Apache::loncommon::findallcourses()) { - %allcal=(%allcal,&readcalendar($_)); - } - + my %allcal=&get_all_calendars(); # ------------------------------- Initialize table and forward backward buttons my ($pm,$py,$fm,$fy)=($month-1,$year,$month+1,$year); if ($pm<1) { ($pm,$py)=(12,$year-1); } if ($fm>12){ ($fm,$fy)=(1,$year+1); } - $r->print('

    '.('',&mt('January'),&mt('February'),&mt('March'), + $r->print('

    '.&mt('Calendar').'

    ' + .'

    '.('',&mt('January'),&mt('February'),&mt('March'), &mt('April'),&mt('May'), &mt('June'),&mt('July'),&mt('August'), &mt('September'),&mt('October'), &mt('November'),&mt('December'))[$month].' '. - $year.'

    '); + $year.' '.&show_timezone().''); # Reached the end of times, give up if (($year<1970) || ($year>2037)) { - $r->print('

    No calendar available for this date.

    '. - 'Current Month'); + $r->print('

    ' + .&mt('No calendar available for this date.') + .'

    ' + .''.&mt('Current Month').'' + .&Apache::loncommon::end_page()); return OK; } + + my $class = "LC_calendar"; + if ($env{'form.pickdate'} eq 'yes') { + $class .= " LC_calendar_pickdate"; + } +# ------------------------------------------------ Determine first day of a week + my $datelocale = &Apache::lonlocal::getdatelocale(); + my $days_in_week = 7; + my $startweek = 0; + if (ref($datelocale)) { + $startweek = $datelocale->first_day_of_week(); + if ($startweek == $days_in_week) { $startweek = 0; } + } + my @days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); + my @localdays; + if ($startweek == 0) { + @localdays = @days; + } else { + my $endday = $days_in_week - $startweek; + for (my $i=0; $i<$days_in_week; $i++) { + if ($i < $endday) { + $localdays[$i] = $days[$i+$startweek]; + } else { + $localdays[$i] = $days[$i-$endday]; + } + } + } + +# ----------------------------------------------------------- Weekday in locale + my $loc_weekday = $weekday - $startweek; + if ($loc_weekday < 0) { + $loc_weekday += $days_in_week; + } + $r->print( - ''.&mt('Previous Month').' '. - ''.&mt('Next Month').''. '   '.&mt('Current Month').'

    '. - ''); + '&year='.$todayhash{'year'}. + ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'
    '. + '
    '. -&tfont(&mt('Sun')) -.''. -&tfont(&mt('Mon')) -.''. -&tfont(&mt('Tue')) -.''. -&tfont(&mt('Wed')) -.''. -&tfont(&mt('Thu')) -.''. -&tfont(&mt('Fri')) -.''. -&tfont(&mt('Sat')) -.'
    '); + for (my $i=0; $i<@localdays; $i++) { + $r->print(''); + } + $r->print(''); - my $tk=&Apache::loncommon::maketime(%firstday); my $outp; my $nm; # ---------------------------------------------------------------- Actual table $r->print(''); - for (my $i=0;$i<$weekday;$i++) { $r->print(&emptycell); } - for (my $i=$weekday;$i<=6;$i++) { + for (my $i=0;$i<$loc_weekday;$i++) { $r->print(&emptycell); } + for (my $i=$loc_weekday;$i<=6;$i++) { ($tk,$nm,$outp)=&showday($tk,0,%allcal); $r->print($outp); } $r->print(''); + my $lastrow = 0; + my $lastday = 0; for (my $k=0;$k<=4;$k++) { - $r->print(''); - for (my $i=0;$i<=6;$i++) { - ($tk,$nm,$outp)=&showday($tk,0,%allcal); - if ($month!=$nm) { $outp=&emptycell; } - $r->print($outp); + if (!$lastrow) { + $r->print(''); + for (my $i=0;$i<=6;$i++) { + if ($lastday) { + $outp = &emptycell(); + } else { + my $currtk = $tk; + ($tk,$nm,$outp)=&showday($tk,0,%allcal); + if ($month!=$nm) { $lastday = 1; } + } + $r->print($outp); + } + if ($lastday) { + $lastrow = 1; + } + $r->print(''); } - $r->print(''); } # ------------------------------------------------------------------- End table - $r->print('
    '.&mt($localdays[$i]).'
    '); + $r->print(''); # ----------------------------------------------------------------- Check marks - %showedcheck=(); - undef %showedcheck; + undef(%showedcheck); # --------------------------------------------------------------- Remove button - if ($allowed) { $r->print(''. + if ($allowed) { $r->print('
    '. &Apache::loncommon::help_open_topic('Calendar_Remove_Announcement').''); } $r->print('

    '. - ''.&mt('Previous Month').' '. - ''.&mt('Next Month').''. '   '.&mt('Current Month').'

    '. ($pickdatemode?'
    ':''). - ''); + ''.&mt('Download your Calendar as iCalendar File').''. + &Apache::loncommon::end_page()); return OK; } 500 Internal Server Error

    Internal Server Error

    The server encountered an internal error or misconfiguration and was unable to complete your request.

    Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

    More information about this error may be available in the server error log.