--- loncom/interface/lonhelper.pm 2007/10/02 00:33:02 1.161.2.1 +++ loncom/interface/lonhelper.pm 2014/02/17 19:36:34 1.192 @@ -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.192 2014/02/17 19:36:34 bisitz 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 @@ -259,7 +261,7 @@ sub real_handler { my $uri = shift; if (!defined($uri)) { $uri = $r->uri(); } $env{'request.uri'} = $uri; - my $filename = '/home/httpd/html' . $uri; + my $filename = $r->dir_config('lonDocRoot').$uri; my $fh = Apache::File->new($filename); my $file; read $fh, $file, 100000000; @@ -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(); } @@ -569,7 +571,7 @@ sub process { # 4: Render the current state to the screen as an HTML page. sub display { my $self = shift; - + my $footer = shift; my $state = $self->{STATES}{$self->{STATE}}; my $result = ""; @@ -587,82 +589,79 @@ sub display { &Apache::loncommon::browser_and_searcher_javascript(). "\n".''; + # Breadcrumbs + my $brcrum = [{'href' => '', + 'text' => 'Helper'}]; + # FIXME: Dynamically add context sensitive breadcrumbs + # depending on the caller, + # e.g. printing, parametrization, etc. + # FIXME: Add breadcrumbs to reflect current helper state + $result .= &Apache::loncommon::start_page($self->{TITLE}, - $browser_searcher_js); - - my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"'); - my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"'); + $browser_searcher_js, + {'bread_crumbs' => $brcrum,}); + + my $previous = HTML::Entities::encode(&mt("Back"), '<>&"'); + my $next = HTML::Entities::encode(&mt("Next"), '<>&"'); # FIXME: This should be parameterized, not concatenated - Jeremy - if (!$state->overrideForm()) { $result.="
"; } + if (!$state->overrideForm()) { $result.=''; } if ($stateHelp) { - $stateHelp = &Apache::loncommon::help_open_topic($stateHelp); + $stateHelp = &Apache::loncommon::help_open_topic($stateHelp); } - $result .= < -

$stateTitle$stateHelp

-HEADER - - $result .= "
"; - - if (!$state->overrideForm()) { - $result .= $self->_saveVars(); - } - $result .= $state->render(); - - $result .= ""; - # Warning: Copy and pasted from below, because it's too much trouble to - # turn this into a subroutine + # Prepare buttons + my $buttons; if (!$state->overrideForm()) { if ($self->{STATE} ne $self->{START_STATE}) { #$result .= '  '; } + $buttons = '

'; # '

'; if ($self->{DONE}) { my $returnPage = $self->{RETURN_PAGE}; - $result .= "" . &mt("End Helper") . ""; + $buttons .= ''.&mt('End Helper').''; } else { - $result .= ' '; - $result .= ''; + $buttons .= '' + .' ' + .'' + .''; } + $buttons .= '

'; # '
'; } - $result .= "
"; - # Warning: Copy and pasted from above, because it's too much trouble to - # turn this into a subroutine + + $result .= '

'.$stateTitle.$stateHelp.'

'; + +# $result .= '
'; + + # Top buttons + $result .= $buttons; + + # Main content of current helper screen if (!$state->overrideForm()) { - if ($self->{STATE} ne $self->{START_STATE}) { - #$result .= '  '; - } - if ($self->{DONE}) { - my $returnPage = $self->{RETURN_PAGE}; - $result .= "" . &mt('End Helper') . ""; - } - else { - $result .= ' '; - $result .= ''; - } + $result .= $self->_saveVars(); } + $result .= $state->render(); + + # Bottom buttons + $result .= $buttons; + #foreach my $key (keys %{$self->{VARS}}) { # $result .= "|$key| -> " . $self->{VARS}->{$key} . "
"; #} - $result .= "
"; +# $result .= ''; $result .= < - - FOOTER - $result .= &Apache::loncommon::end_page(); + $result .= $footer.&Apache::loncommon::end_page(); # Handle writing out the vars to the file my $file = Apache::File->new('>'.$self->{FILENAME}); print $file $self->_varsInFile(); @@ -1008,6 +1007,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 +1025,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 @@ -1466,9 +1476,9 @@ BUTTONS HTML::Entities::encode($choice->[1],"<>&\"'") . "'"; if ($checkedChoices{$choice->[1]}) { - $result .= " checked='checked' "; + $result .= " checked='checked'"; } - $result .= qq{id="id$id"}; + $result .= qq{ id="id$id"}; my $choiceLabel = $choice->[0]; if ($choice->[3]) { # if we need to evaluate this choice $choiceLabel = "sub { my $helper = shift; my $state = shift;" . @@ -1476,7 +1486,7 @@ BUTTONS $choiceLabel = eval($choiceLabel); $choiceLabel = &$choiceLabel($helper, $self); } - $result .= "/> ".qq{' + my $anytimetext = &mt('Any time'); + if (($var eq 'startreserve') || ($var eq 'endreserve')) { + $anytimetext = &mt('Any time before slot starts'); + } elsif (($var eq 'startunique') || ($var eq 'endunique')) { + $anytimetext = &mt('No restriction on uniqueness'); + } + $result.="name='${var}anytime'/>".$anytimetext.'' } return $result; @@ -1912,7 +1931,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 +1942,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 +1998,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 +2038,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 @@ -2022,6 +2072,49 @@ than 1 part. evaluated with "sub { my $helper = shift; my $state = shift;" and "}", with the return value used as the mapurl. +=item *