--- loncom/interface/lonhelper.pm 2007/10/02 00:33:02 1.161.2.1 +++ loncom/interface/lonhelper.pm 2009/03/17 11:13:59 1.171 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # .helper XML handler to implement the LON-CAPA helper # -# $Id: lonhelper.pm,v 1.161.2.1 2007/10/02 00:33:02 albertel Exp $ +# $Id: lonhelper.pm,v 1.171 2009/03/17 11:13:59 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -188,6 +188,8 @@ use Apache::lonlocal; use Apache::lonnet; use Apache::longroup; use Apache::lonselstudent; + + use LONCAPA; # Register all the tags with the helper, so the helper can @@ -529,7 +531,7 @@ sub process { # Phase 1: Post processing for state of previous screen (which is actually # the "current state" in terms of the helper variables), if it wasn't the # beginning state. - if ($self->{STATE} ne "START" || $env{"form.SUBMIT"} eq &mt("Next ->")) { + if ($self->{STATE} ne "START" || $env{"form.SUBMIT"} eq &mt("Next")) { my $prevState = $self->{STATES}{$self->{STATE}}; $prevState->postprocess(); } @@ -590,8 +592,8 @@ sub display { $result .= &Apache::loncommon::start_page($self->{TITLE}, $browser_searcher_js); - my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"'); - my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"'); + my $previous = HTML::Entities::encode(&mt("Back"), '<>&"'); + my $next = HTML::Entities::encode(&mt("Next"), '<>&"'); # FIXME: This should be parameterized, not concatenated - Jeremy @@ -624,9 +626,9 @@ HEADER $result .= "" . &mt("End Helper") . ""; } else { - $result .= ' '; - $result .= ''; + $result .= ''; } } @@ -643,9 +645,9 @@ HEADER $result .= "" . &mt('End Helper') . ""; } else { - $result .= ' '; - $result .= ''; + $result .= ''; } } @@ -1008,6 +1010,9 @@ sub start_message { if (defined($token->[2]{'nextstate'})) { $paramHash->{NEXTSTATE} = $token->[2]{'nextstate'}; } + if (defined($token->[2]{'type'})) { + $paramHash->{TYPE} = $token->[2]{'type'}; + } return ''; } @@ -1023,7 +1028,15 @@ sub end_message { sub render { my $self = shift; - + + if ($self->{TYPE} =~ /^\s*warning\s*$/i) { + $self->{MESSAGE_TEXT} = + ''. $self->{MESSAGE_TEXT}.''; + } + if ($self->{TYPE} =~ /^\s*error\s*$/i) { + $self->{MESSAGE_TEXT} = + ''. $self->{MESSAGE_TEXT}.''; + } return $self->{MESSAGE_TEXT}; } # If a NEXTSTATE was given, switch to it @@ -1497,12 +1510,15 @@ sub postprocess { my $self = shift; my $chosenValue = $env{'form.' . $self->{'variable'} . '_forminput'}; + if (!defined($chosenValue) && !$self->{'allowempty'}) { $self->{ERROR_MSG} = &mt("You must choose one or more choices to continue."); return 0; } + + if (ref($chosenValue)) { $helper->{VARS}->{$self->{'variable'}} = join('|||', @$chosenValue); } @@ -1714,7 +1730,7 @@ no strict; use strict; use Apache::lonlocal; # A localization nightmare use Apache::lonnet; -use Time::localtime; +use DateTime; BEGIN { &Apache::lonhelper::register('Apache::lonhelper::date', @@ -1764,14 +1780,13 @@ sub render { my $time=time; my ($anytime,$onclick); - # first check VARS for a valid new value from the user # then check DEFAULT_VALUE for a valid default time value # otherwise pick now as reasonably good time if (defined($helper->{VARS}{$var}) && $helper->{VARS}{$var} > 0) { - $date = localtime($helper->{VARS}{$var}); + $date = &get_date_object($helper->{VARS}{$var}); } elsif (defined($self->{DEFAULT_VALUE})) { my $valueFunc = eval($self->{DEFAULT_VALUE}); die('Error in default value code for variable ' . @@ -1779,17 +1794,17 @@ sub render { $time = &$valueFunc($helper, $self); if (lc($time) eq 'anytime') { $anytime=1; - $date = localtime(time); + $date = &get_date_object(time); $date->min(0); } elsif (defined($time) && $time ne 0) { - $date = localtime($time); + $date = &get_date_object($time); } else { # leave date undefined so it'll default to now } } if (!defined($date)) { - $date = localtime(time); + $date = &get_date_object(time); $date->min(0); } @@ -1806,12 +1821,12 @@ sub render { my $i; $result .= "\n"; @@ -1830,7 +1845,7 @@ sub render { # Year $result .= "\n"; } + $result .= ' '.$date->time_zone_short_name().' '; if ($self->{'anytime'}) { $result.=(< @@ -1912,7 +1928,8 @@ sub postprocess { if ($env{'form.' . $var . 'anytime'}) { $helper->{VARS}->{$var} = undef; } else { - my $month = $env{'form.' . $var . 'month'}; + my $month = $env{'form.' . $var . 'month'}; + $month ++; my $day = $env{'form.' . $var . 'day'}; my $year = $env{'form.' . $var . 'year'}; my $min = 0; @@ -1922,25 +1939,40 @@ sub postprocess { $hour = $env{'form.' . $var . 'hour'}; } - my $chosenDate; - eval {$chosenDate = Time::Local::timelocal(0, $min, $hour, $day, $month, $year);}; + my ($chosenDate,$checkDate); + my $timezone = &Apache::lonlocal::gettimezone(); + my $dt; + eval { + $dt = DateTime->new( year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $min, + second => 0, + time_zone => $timezone, + ); + }; + my $error = $@; + if (!$error) { + $chosenDate = $dt->epoch; + $checkDate = &get_date_object($chosenDate); + } # Check to make sure that the date was not automatically co-erced into a # valid date, as we want to flag that as an error # This happens for "Feb. 31", for instance, which is coerced to March 2 or # 3, depending on if it's a leap year - my $checkDate = localtime($chosenDate); if ($error || $checkDate->mon != $month || $checkDate->mday != $day || - $checkDate->year + 1900 != $year) { + $checkDate->year != $year) { unless (Apache::lonlocal::current_language()== ~/^en/) { $self->{ERROR_MSG} = &mt("Invalid date entry"); return 0; } # LOCALIZATION FIXME: Needs to be parameterized - $self->{ERROR_MSG} = "Can't use " . $months[$month] . " $day, $year as a " - . "date because it doesn't exist. Please enter a valid date."; + $self->{ERROR_MSG} = "Can't use ".$months[$env{'form.'.$var.'month'}]. " $day, $year as a ". + "date because it doesn't exist. Please enter a valid date."; return 0; } @@ -1963,6 +1995,20 @@ sub postprocess { return 1; } + +sub get_date_object { + my ($epoch) = @_; + my $dt = DateTime->from_epoch(epoch => $epoch) + ->set_time_zone(&Apache::lonlocal::gettimezone()); + my $lang = Apache::lonlocal::current_language(); + if ($lang ne '') { + eval { + $dt->set_locale($lang); + }; + } + return $dt; +} + 1; package Apache::lonhelper::resource; @@ -1989,7 +2035,8 @@ folders that have all of their contained be filtered out. The 'addstatus' attribute, if true, will add the icon and long status display columns to the display. The 'addparts' attribute will add in a part selector beside problems that have more -than 1 part. +than 1 part. The 'includecourse' attribute if true, will include +the toplevel default.sequence in the results. =head3 SUB-TAGS @@ -2062,6 +2109,7 @@ sub start_resource { $helper->declareVar($paramHash->{'variable'}.'_part'); } $paramHash->{'closeallpages'} = $token->[2]{'closeallpages'}; + $paramHash->{'include_top_level_map'} = $token->[2]{'includecourse'}; return ''; } @@ -2387,6 +2435,7 @@ RADIO 'resource_no_folder_link' => 1, 'closeAllPages' => $self->{'closeallpages'}, 'suppressEmptySequences' => $self->{'suppressEmptySequences'}, + 'include_top_level_map' => $self->{'include_top_level_map'}, 'iterator_map' => $mapUrl } ); @@ -2402,6 +2451,21 @@ sub postprocess { $self->{ERROR_MSG} = 'You must choose at least one resource to continue.'; return 0; } + # For each of the attached options. If it's env var is undefined, set it to + # an empty string instead.. an undef'd env var means no choices selected. + # + + my $option_vars = $self->{OPTION_VARS}; + if ($option_vars) { + foreach my $var (@$option_vars) { + my $env_name = "form.".$var."_forminput"; + if (!defined($env{$env_name})) { + $env{$env_name} = ''; + $helper->{VARS}->{$var} = ''; + } + } + } + if (defined($self->{NEXTSTATE})) { $helper->changeState($self->{NEXTSTATE}); @@ -2818,17 +2882,17 @@ BUTTONS &Apache::loncacc::constructaccess($subdir, $Apache::lonnet::perlvar{'lonDefDomain'}); $metadir='/res/'.$domain.'/'.$user.'/'.$2; - @fileList = &Apache::lonnet::dirlist($subdir, $domain, $user, ''); + @fileList = &Apache::lonnet::dirlist($subdir,$domain,$user,undef,undef,'/'); } elsif ($subdir =~ m|^~([^/]+)/(.*)$|) { $subdir='/home/'.$1.'/public_html/'.$2; my ($user,$domain)= &Apache::loncacc::constructaccess($subdir, $Apache::lonnet::perlvar{'lonDefDomain'}); $metadir='/res/'.$domain.'/'.$user.'/'.$2; - @fileList = &Apache::lonnet::dirlist($subdir, $domain, $user, ''); + @fileList = &Apache::lonnet::dirlist($subdir,$domain,$user,undef,undef,'/'); } else { # local library server resource space - @fileList = &Apache::lonnet::dirlist($subdir, $env{'user.domain'}, $env{'user.name'}, ''); + @fileList = &Apache::lonnet::dirlist($subdir,$env{'user.domain'},$env{'user.name'},undef,undef,'/'); } # Sort the fileList into order @@ -3498,8 +3562,8 @@ sub render { } my $finish=&mt('Finish Course Initialization'); } - my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"'); - my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"'); + my $previous = HTML::Entities::encode(&mt("Back"), '<>&"'); + my $next = HTML::Entities::encode(&mt("Next"), '<>&"'); my $target = " target='loncapaclient'"; if (($env{'browser.interface'} eq 'textual') || ($env{'environment.remote'} eq 'off')) { $target=''; } @@ -3589,7 +3653,7 @@ sub render { # Print the granularity, depending on the action if ($vars->{GRANULARITY} eq 'whole_course') { - $resourceString .= '
  • '.&mt('for all resources in the course').'
  • '; + $resourceString .= '
  • '.&mt('for [_1]all resources in the course[_2]','','').'
  • '; if ($vars->{TARGETS} eq 'course') { $level = 14; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { @@ -3604,10 +3668,16 @@ sub render { $paramlevel = 'general'; } elsif ($vars->{GRANULARITY} eq 'map') { my $navmap = Apache::lonnavmaps::navmap->new(); - my $res = $navmap->getByMapPc($vars->{RESOURCE_ID}); - my $title = $res->compTitle(); - $symb = $res->symb(); - $resourceString .= '
  • '.&mt('for the map named [_1]',"$title").'
  • '; + if (defined($navmap)) { + my $res = $navmap->getByMapPc($vars->{RESOURCE_ID}); + my $title = $res->compTitle(); + $symb = $res->symb(); + $resourceString .= '
  • '.&mt('for the map named [_1]',"$title").'
  • '; + } else { + $resourceString .= '
  • '.&mt('for the map ID [_1] (name unavailable)',''.$vars->{RESOURCE_ID}.'').'
  • '; + &Apache::lonnet::logthis('Retrieval of map title failed in lonhelper.pm - could not create navmap object for course.'); + + } if ($vars->{TARGETS} eq 'course') { $level = 13; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { @@ -3620,13 +3690,18 @@ sub render { $affectedResourceId = $vars->{RESOURCE_ID}; $paramlevel = 'map'; } else { - my $navmap = Apache::lonnavmaps::navmap->new(); - my $res = $navmap->getById($vars->{RESOURCE_ID}); my $part = $vars->{RESOURCE_ID_part}; if ($part ne 'All Parts' && $part) { $parm_name=~s/^0/$part/; } else { $part=&mt('All Parts'); } - $symb = $res->symb(); - my $title = $res->compTitle(); - $resourceString .= '
  • '.&mt('for the resource named [_1] part [_2]',"$title","$part").'
  • '; + my $navmap = Apache::lonnavmaps::navmap->new(); + if (defined($navmap)) { + my $res = $navmap->getById($vars->{RESOURCE_ID}); + $symb = $res->symb(); + my $title = $res->compTitle(); + $resourceString .= '
  • '.&mt('for the resource named [_1] part [_2]',"$title","$part").'
  • '; + } else { + $resourceString .= '
  • '.&mt('for the resource ID [_1] (name unavailable) part [_2]',''.$vars->{RESOURCE_ID}.'',"$part").'
  • '; + &Apache::lonnet::logthis('Retrieval of resource title failed in lonhelper.pm - could not create navmap object for course.'); + } if ($vars->{TARGETS} eq 'course') { $level = 10; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { @@ -3705,7 +3780,7 @@ sub render { # Print targets if ($vars->{TARGETS} eq 'course') { - $result .= '
  • '.&mt('for all students in course').'
  • '; + $result .= '
  • '.&mt('for [_1]all students in course[_2]','','').'
  • '; } elsif ($vars->{TARGETS} eq 'section') { my $section = $vars->{SECTION_NAME}; $result .= '
  • '.&mt('for section [_1]',"$section").'
  • '; @@ -3730,7 +3805,8 @@ sub render { # Print value if ($vars->{ACTION_TYPE} ne 'tries' && $vars->{ACTION_TYPE} ne 'weight') { - $result .= '
  • '.&mt('to [_1] ([_2])',"".ctime($vars->{PARM_DATE})."",Apache::lonnavmaps::timeToHumanString($vars->{PARM_DATE}))."
  • \n"; + my $showdate = &Apache::lonlocal::locallocaltime($vars->{PARM_DATE}); + $result .= '
  • '.&mt('to [_1] ([_2])',"".$showdate."",Apache::lonnavmaps::timeToHumanString($vars->{PARM_DATE}))."
  • \n"; } # print pres_marker