--- loncom/interface/lonhelper.pm 2006/04/06 22:30:52 1.136 +++ loncom/interface/lonhelper.pm 2007/08/29 00:46:39 1.162 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # .helper XML handler to implement the LON-CAPA helper # -# $Id: lonhelper.pm,v 1.136 2006/04/06 22:30:52 foxr Exp $ +# $Id: lonhelper.pm,v 1.162 2007/08/29 00:46:39 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -81,25 +81,28 @@ State tags are also required to have an human name of the state, and will be displayed as the header on top of the screen for the user. +State tags may also optionally have an attribute "help" which should be +the filename of a help file, this will add a blue ? to the title. + =head2 Example Helper Skeleton An example of the tags so far: - + -Of course this does nothing. In order for the wizard to do something, it is -necessary to put actual elements into the wizard. Documentation for each +Of course this does nothing. In order for the helper to do something, it is +necessary to put actual elements into the helper. Documentation for each of these elements follows. =head1 Creating a Helper With Code, Not XML -In some situations, such as the printing wizard (see lonprintout.pm), +In some situations, such as the printing helper (see lonprintout.pm), writing the helper in XML would be too complicated, because of scope issues or the fact that the code actually outweighs the XML. It is possible to create a helper via code, though it is a little odd. @@ -183,6 +186,9 @@ use Apache::File; use Apache::lonxml; 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 # push and pop them @@ -331,7 +337,8 @@ sub start_state { } Apache::lonhelper::state->new($token->[2]{'name'}, - $token->[2]{'title'}); + $token->[2]{'title'}, + $token->[2]{'help'}); return ''; } @@ -361,6 +368,7 @@ use Apache::loncommon; use Apache::File; use Apache::lonlocal; use Apache::lonnet; +use LONCAPA; sub new { my $proto = shift; @@ -466,9 +474,8 @@ sub _saveVars { sub _varsInFile { my $self = shift; my @vars = (); - for my $key (keys %{$self->{VARS}}) { - push @vars, &Apache::lonnet::escape($key) . '=' . - &Apache::lonnet::escape($self->{VARS}->{$key}); + for my $key (keys(%{$self->{VARS}})) { + push(@vars, &escape($key) . '=' . &escape($self->{VARS}->{$key})); } return join ('&', @vars); } @@ -483,7 +490,7 @@ sub declareVar { $self->{VARS}->{$var} = ''; } - my $envname = 'form.' . $var . '.forminput'; + my $envname = 'form.' . $var . '_forminput'; if (defined($env{$envname})) { if (ref($env{$envname})) { $self->{VARS}->{$var} = join('|||', @{$env{$envname}}); @@ -574,6 +581,7 @@ sub display { # Phase 4: Display. my $stateTitle=&mt($state->title()); + my $stateHelp= $state->help(); my $browser_searcher_js = ' - + RADIO $env{'form.condition'} = !$self->{'toponly'}; @@ -2292,113 +2513,6 @@ sub render { my $buttons = ''; my $var = $self->{'variable'}; - if ($self->{'multichoice'}) { - $result = < -// - -SCRIPT - - my %lt=&Apache::lonlocal::texthash( - 'ocs' => "Select Only Current Students", - 'ues' => "Unselect Expired Students", - 'sas' => "Select All Students", - 'uas' => "Unselect All Students", - 'sfsg' => "Select Current Students for Section/Group", - 'ufsg' => "Unselect for Section/Group"); - - $buttons = < - - - - - - - -

-
-BUTTONS - $result .= $buttons; - - } if (defined $self->{ERROR_MSG}) { $result .= '' . $self->{ERROR_MSG} . '

'; @@ -2416,203 +2530,62 @@ BUTTONS %defaultUsers = map { if ($_) {($_,1) } } @defaultUsers; delete($defaultUsers{''}); } - my $choices = []; - my $expired_students = []; # Will hold expired students. - # Load up the non-students, if necessary - if ($self->{'coursepersonnel'}) { - my %coursepersonnel = Apache::lonnet::get_course_adv_roles(); - for (sort keys %coursepersonnel) { - for my $role (split /,/, $coursepersonnel{$_}) { - # extract the names so we can sort them - my @people; - - for (split /,/, $role) { - push @people, [split /:/, $role]; - } - - @people = sort { $a->[0] cmp $b->[0] } @people; - - for my $person (@people) { - push @$choices, [join(':', @$person), $person->[0], '', $_]; - } - } - } - } - # Constants - my $section = Apache::loncoursedata::CL_SECTION(); - my $fullname = Apache::loncoursedata::CL_FULLNAME(); - my $status = Apache::loncoursedata::CL_STATUS(); + my ($course_personnel, + $current_members, + $expired_members, + $future_members) = + &Apache::lonselstudent::get_people_in_class($env{'request.course.sec'}); - # Load up the students - my $classlist = &Apache::loncoursedata::get_classlist(); - my @keys = keys %{$classlist}; - # Sort by: Section, name - @keys = sort { - if ($classlist->{$a}->[$section] ne $classlist->{$b}->[$section]) { - return $classlist->{$a}->[$section] cmp $classlist->{$b}->[$section]; - } - return $classlist->{$a}->[$fullname] cmp $classlist->{$b}->[$fullname]; - } @keys; - # - # now add the fancy section choice... first enumerate the sections: - if ($self->{'multichoice'}) { - my %sections; - for my $key (@keys) { - my $section_name = $classlist->{$key}->[$section]; - if ($section_name ne "") { - $sections{$section_name} = 1; - } - } - # The variable $choice_widget will have the html to make the choice - # selector. - my $size=5; - if (scalar(keys(%sections)) < 5) { - $size=scalar(keys(%sections)); - } - my $choice_widget = '\n"; - - # Build a table without any borders to contain the section based - # selection: - - my $section_selectors =< - - For Sections:$choice_widget - - - - - - - - -
-SECTIONSELECT - $result .= $section_selectors; - } - # username, fullname, section, type - for (@keys) { - # We split the active students into the choices array and - # inactive ones into expired_students so that we can put them in 2 separate - # tables. - - if ( $classlist->{$_}->[$status] eq - 'Active') { - push @$choices, [$_, $classlist->{$_}->[$fullname], - $classlist->{$_}->[$section], - $classlist->{$_}->[$status], 'Student']; - } else { - push @$expired_students, [$_, $classlist->{$_}->[$fullname], - $classlist->{$_}->[$section], - $classlist->{$_}->[$status], 'Student']; - } + # Load up the non-students, if necessary + + if ($self->{'coursepersonnel'}) { + unshift @$current_members, (@$course_personnel); } - my $name = $self->{'coursepersonnel'} ? &mt('Name') : &mt('Student Name'); - my $type = 'radio'; - if ($self->{'multichoice'}) { $type = 'checkbox'; } - $result .= "\n"; - $result .= "". - "" . - "" . - "" . - ""; - my $checked = 0; - # - # Give the active students and staff: - # - for my $choice (@$choices) { - $result .= "\n\n\n\n"; - } - $result .= "
$name" . &mt('Section') . "".&mt('Status')."" . &mt("Role") . "".&mt('Username').":".&mt('Domain')."
[0]; - if (exists($defaultUsers{$user})) { - $result .= " checked='checked' "; - $checked = 1; - } - } elsif (!$self->{'multichoice'} && !$checked) { - $result .= " checked='checked' "; - $checked = 1; - } - $result .= - " value='" . HTML::Entities::encode($choice->[0] . ':' - .$choice->[2] . ':' - .$choice->[1] . ':' - .$choice->[3], "<>&\"'") - . "' />" - . HTML::Entities::encode($choice->[1],'<>&"') - . "" - . HTML::Entities::encode($choice->[2],'<>&"') - . "" - . HTML::Entities::encode($choice->[3],'<>&"') - . "" - . HTML::Entities::encode($choice->[4],'<>&"') - . "" - . HTML::Entities::encode($choice->[0],'<>&"') - . "
\n\n"; + # Current personel + + $result .= '

'.&mt('Select Currently Enrolled Students and Active Course Personnel').'

'; + $result .= &Apache::lonselstudent::render_student_list( $current_members, + "helpform", + "current", + \%defaultUsers, + $self->{'multichoice'}, + $self->{'variable'}, + 1); + # If activeonly is not set then we can also give the expired students: # - if (!$self->{'activeonly'} && ((scalar @$expired_students) > 0)) { - $result .= "

Inactive students:

\n"; - $result .= < - - - - - -INACTIVEBUTTONS - $result .= "\n"; - - for my $choice (@$expired_students) { - $result .= "\n\n\n\n"; - } - $result .= "
[0]; - if (exists($defaultUsers{$user})) { - $result .= " checked='checked' "; - $checked = 1; - } - } elsif (!$self->{'multichoice'} && !$checked) { - $result .= " checked='checked' "; - $checked = 1; - } - $result .= - " value='" . HTML::Entities::encode($choice->[0] . ':' - .$choice->[2] . ':' - .$choice->[1] . ':' - .$choice->[3], "<>&\"'") - . "' />" - . HTML::Entities::encode($choice->[1],'<>&"') - . "" - . HTML::Entities::encode($choice->[2],'<>&"') - . "" - . HTML::Entities::encode($choice->[3],'<>&"') - . "" - . HTML::Entities::encode($choice->[4],'<>&"') - . "" - . HTML::Entities::encode($choice->[0],'<>&"') - . "
\n"; - + if (!$self->{'activeonly'} && ((scalar(@$future_members)) > 0)) { + + # And future. + + $result .= '

'.&mt('Select Future Enrolled Students and Future Course Personnel').'

'; + + $result .= &Apache::lonselstudent::render_student_list( $future_members, + "helpform", + "future", + \%defaultUsers, + $self->{'multichoice'}, + $self->{'variable'}, + 0); + } + if (!$self->{'activeonly'} && ((scalar(@$expired_members)) > 0)) { + # Past + + $result .= '

'.&mt('Select Previously Enrolled Students and Inactive Course Personnel').'

'; + $result .= &Apache::lonselstudent::render_student_list($expired_members, + "helpform", + "past", + \%defaultUsers, + $self->{'multichoice'}, + $self->{'variable'}, + 0); } @@ -2623,7 +2596,7 @@ INACTIVEBUTTONS sub postprocess { my $self = shift; - my $result = $env{'form.' . $self->{'variable'} . '.forminput'}; + my $result = $env{'form.' . $self->{'variable'} . '_forminput'}; if (!$result && !$self->{'emptyallowed'}) { if ($self->{'coursepersonnel'}) { $self->{ERROR_MSG} = @@ -2808,7 +2781,7 @@ sub render { function checkall(value, checkName) { for (i=0; i" . "{'multichoice'} && $choices == 0) { $result .= ' checked="checked"'; @@ -2986,7 +2959,7 @@ sub fileState { sub postprocess { my $self = shift; - my $result = $env{'form.' . $self->{'variable'} . '.forminput'}; + my $result = $env{'form.' . $self->{'variable'} . '_forminput'}; if (!$result) { $self->{ERROR_MSG} = 'You must choose at least one file '. 'to continue.'; @@ -3056,26 +3029,29 @@ sub start_section { my $section = Apache::loncoursedata::CL_SECTION(); my $classlist = Apache::loncoursedata::get_classlist(); - foreach (keys %$classlist) { - my $sectionName = $classlist->{$_}->[$section]; - if (!$sectionName) { + foreach my $user (keys(%$classlist)) { + my $section_name = $classlist->{$user}[$section]; + if (!$section_name) { $choices{"No section assigned"} = ""; } else { - $choices{$sectionName} = $sectionName; + $choices{$section_name} = $section_name; } } - for my $sectionName (sort(keys(%choices))) { - push @{$paramHash->{CHOICES}}, [$sectionName, $sectionName]; + if (exists($choices{"No section assigned"})) { + push(@{$paramHash->{CHOICES}}, + ['No section assigned','No section assigned']); + delete($choices{"No section assigned"}); + } + for my $section_name (sort {lc($a) cmp lc($b) } (keys(%choices))) { + push @{$paramHash->{CHOICES}}, [$section_name, $section_name]; } return if ($token->[2]{'onlysections'}); # add in groups to the end of the list - my %curr_groups; - if (&Apache::loncommon::coursegroups(\%curr_groups)) { - foreach my $group_name (sort(keys(%curr_groups))) { - push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]); - } + my %curr_groups = &Apache::longroup::coursegroups(); + foreach my $group_name (sort(keys(%curr_groups))) { + push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]); } } @@ -3137,11 +3113,9 @@ sub start_group { # Populate the CHOICES element my %choices; - my %curr_groups; - if (&Apache::loncommon::coursegroups(\%curr_groups)) { - foreach my $group_name (sort(keys(%curr_groups))) { - push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]); - } + my %curr_groups = &Apache::longroup::coursegroups(); + foreach my $group_name (sort {lc($a) cmp lc($b)} (keys(%curr_groups))) { + push(@{$paramHash->{CHOICES}}, [$group_name, $group_name]); } } @@ -3221,7 +3195,7 @@ sub render { $result .= '

' . $self->{ERROR_MSG} . '

'; } - $result .= '{'variable'} . '_forminput"'; if (defined($self->{'size'})) { $result .= ' size="' . $self->{'size'} . '"'; @@ -3248,7 +3222,7 @@ sub postprocess { if (defined($self->{VALIDATOR})) { my $validator = eval($self->{VALIDATOR}); - die 'Died during evaluation of evaulation code; Perl said: ' . $@ if $@; + die 'Died during evaluation of validator code; Perl said: ' . $@ if $@; my $invalid = &$validator($helper, $state, $self, $self->getValue()); if ($invalid) { $self->{ERROR_MSG} = $invalid; @@ -3354,7 +3328,8 @@ sub start_clause { die 'Error in clause of condition, Perl said: ' . $@ if $@; if (!&$clause($helper, $paramHash)) { # Discard all text until the /condition. - &Apache::lonxml::get_all_text('/condition', $parser); + my $end_tag = $paramHash->{SKIPTAG} || '/condition'; + &Apache::lonxml::get_all_text($end_tag, $parser); } } @@ -3559,7 +3534,7 @@ sub overrideForm { package Apache::lonhelper::parmwizfinal; -# This is the final state for the parmwizard. It is not generally useful, +# This is the final state for the parm helper. It is not generally useful, # so it is not perldoc'ed. It does its own processing. # It is represented with , and # should later be moved to lonparmset.pm . @@ -3627,8 +3602,10 @@ sub render { if ($vars->{GRANULARITY} eq 'whole_course') { $resourceString .= '
  • '.&mt('for all resources in the course').'
  • '; if ($vars->{TARGETS} eq 'course') { - $level = 11; # general course, see lonparmset.pm perldoc + $level = 14; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { + $level = 9; + } elsif ($vars->{TARGETS} eq 'group') { $level = 6; } else { $level = 3; @@ -3643,8 +3620,10 @@ sub render { $symb = $res->symb(); $resourceString .= '
  • '.&mt('for the map named [_1]',"$title").'
  • '; if ($vars->{TARGETS} eq 'course') { - $level = 10; # general course, see lonparmset.pm perldoc + $level = 13; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { + $level = 8; + } elsif ($vars->{TARGETS} eq 'group') { $level = 5; } else { $level = 2; @@ -3660,8 +3639,10 @@ sub render { my $title = $res->compTitle(); $resourceString .= '
  • '.&mt('for the resource named [_1] part [_2]',"$title","$part").'
  • '; if ($vars->{TARGETS} eq 'course') { - $level = 7; # general course, see lonparmset.pm perldoc + $level = 10; # general course, see lonparmset.pm perldoc } elsif ($vars->{TARGETS} eq 'section') { + $level = 7; + } elsif ($vars->{TARGETS} eq 'group') { $level = 4; } else { $level = 1;