# The LearningOnline Network with CAPA # # Sequence Handler # # $Id: lonsequence.pm,v 1.45 2014/12/15 00:46:52 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonsequence; use strict; use Apache::lonnet; use Apache::Constants qw(:common :http REDIRECT); use GDBM_File; use LONCAPA::map(); use LONCAPA; use Apache::lonpageflip(); use Apache::loncommon(); use Apache::groupsort(); use Apache::lonlocal; use HTML::Entities(); my %selhash; my $successtied; # ----------------------------------------- Attempt to read from resource space sub attemptread { my ($fn,$unsorted)=@_; &Apache::lonnet::repcopy($fn); if (-e $fn) { return &LONCAPA::map::attemptread($fn,$unsorted); } else { return (); } } sub mapread { my $fn=shift; &Apache::lonnet::repcopy($fn); if (-e $fn) { return &LONCAPA::map::mapread($fn,''); } else { return (); } } # ---------------------------------------------------------------- View Handler sub viewmap { my ($r,$url)=@_; my $js; if ($env{'form.forceselect'}) { $js = (< function select_group() { window.location="/adm/groupsort?catalogmode=groupsec&mode=rat&acts="+document.forms.fileattr.acts.value; } function queue(val) { if (eval("document.forms."+val+".filelink.checked")) { var l=val.length; var v=val.substring(4,l); document.forms.fileattr.acts.value+='1a'+v+'b'; } else { var l=val.length; var v=val.substring(4,l); document.forms.fileattr.acts.value+='0a'+v+'b'; } } ENDSCRIPT } $r->print(&Apache::loncommon::start_page('Map Contents',$js). '

'.$url.'

'); # ------------------ This is trying to select. Provide buttons and tie %selhash if ($env{'form.forceselect'}) { $r->print(< ENDSELECT my $diropendb = LONCAPA::tempdir() . "$env{'user.domain'}\_$env{'user.name'}_sel_res.db"; if (tie(%selhash,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) { if ($env{'form.launch'} eq '1') { &start_fresh_session(); } $successtied=1; # - Evaluate actions from previous page (both cumulatively and chronologically) if ($env{'form.catalogmode'} eq 'import') { &Apache::groupsort::update_actions_hash(\%selhash); } # - } } # ----------------------------- successtied is now '1' if in working selectmode my ($errtext,$fatal)=&mapread(&Apache::lonnet::filelocation('',$url),''); if ($fatal==1) { $r->print('

' .&mt('Map contents are not shown in order.') .'


'); } my $idx=0; foreach my $entry (&attemptread(&Apache::lonnet::filelocation('',$url))) { if (defined($entry)) { $idx++; if ($successtied) { $r->print('
'); } my ($title,$url)=split(/\:/,$entry); $title = &LONCAPA::map::qtescape($title); unless ($title) { $title=(split(/\//,$url))[-1] }; my $enc_title = &HTML::Entities::encode($title,'\'"<>&'); unless ($title) { $title=''.&mt('Empty').''; $enc_title = &mt('Empty'); } $url = &LONCAPA::map::qtescape($url); my $enc_url = &HTML::Entities::encode($url,'\'"<>&'); if ($url) { if ($successtied) { my $checked=''; if ($selhash{'store_'.$url}) { $checked=' checked="checked"'; } $selhash{"pre_${idx}_link"}=$url; $selhash{"pre_${idx}_title"}=$title; $url = &HTML::Entities::encode($url, '\'"<>&'); $r->print(< ENDCHECKBOX } $r->print(''); } $r->print($enc_title); if ($url) { $r->print(''); } if ($successtied) { $r->print(''); } else { $r->print('
'); } } } $r->print(&Apache::loncommon::end_page()); if ($successtied) { untie %selhash; } } # ----------------------------------------------------------- Clean out selhash sub start_fresh_session { foreach my $item (keys(%selhash)) { if ($item =~ /^pre_/) { delete $selhash{$item}; } if ($item =~ /^store/) { delete $selhash{$item}; } } } # ================================================================ Main Handler sub handler { my $r=shift; if ($r->header_only) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['forceselect','launch']); my %hash; my %bighash; my $requrl=$r->uri; $successtied=0; # ------------------------------------------------------------ Tie symb db file my $disurl=''; my $dismapid=''; my $exitdisid = ''; my $arrow_dir = ''; my $is_encrypted = ''; if (($env{'request.course.fn'}) && (!$env{'form.forceselect'})) { my $last; if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', &GDBM_READER(),0640)) { $last=$hash{'last_direction'}; untie(%hash); } my $direction=''; my $prevmap=''; if ($last) { ($prevmap,undef,$direction)=&Apache::lonnet::decode_symb($last); } # ------------------------------------------------------------- Tie big db file if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', &GDBM_READER(),0640)) { my $disid=''; my $randomout =''; if ($direction eq 'back') { $disid=$bighash{'map_finish_'.$requrl}; } else { $disid=$bighash{'map_start_'.$requrl}; } if ($disid) { $disurl=$bighash{'src_'.$disid}; $dismapid=(split(/\./,$disid))[1]; if (!$env{'request.role.adv'}) { $randomout = $bighash{'randomout_'.$disid}; } if (!$env{'request.role.adv'}) { $is_encrypted = $bighash{'encrypted_'.$disid}; } } elsif (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', &GDBM_READER(),0640)) { $last=$hash{'last_known'}; untie(%hash); } # ----------- If this is an empty one, or hidden, skip to next non-empty or non-hidden one while ( ((!$disurl) && ($disid)) || ($randomout && $disid) ) { $direction=($direction?$direction:'forward'); ($disid,$requrl)= &Apache::lonpageflip::fullmove($disid, &Apache::lonnet::declutter($requrl),$direction); if ($disid) { $disurl=$bighash{'src_'.$disid}; $dismapid=(split(/\./,$disid))[1]; if (!$env{'request.role.adv'}) { $randomout = $bighash{'randomout_'.$disid}; } if (!$env{'request.role.adv'}) { $is_encrypted = $bighash{'encrypted_'.$disid}; } } } $exitdisid = $disid; $arrow_dir = $direction; # --------------------------------------- Untie hash, make sure to come by here untie(%bighash); } } # now either disurl is set (going to first page), or we need another display if ($disurl) { # -------------------------------------------------- Has first or last resource my $showdisurl = $disurl; if ($is_encrypted) { $showdisurl = &Apache::lonenc::encrypted($disurl); } &Apache::lonnet::symblist($requrl,$disurl => [$disurl,$dismapid], 'last_known' => [$disurl,$dismapid]); &Apache::loncommon::content_type($r,'text/html'); $r->header_out(Location => &Apache::lonnet::absolute_url($ENV{'SERVER_NAME'}). $showdisurl); return REDIRECT; } else { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; if ($exitdisid eq '' && $arrow_dir ne '') { my %lt =&Apache::lonlocal::texthash( 'nere' => 'Next resource could not be displayed', 'goba' => 'Go Back', 'nacc' => 'Course Contents', ); if (&Apache::loncommon::course_type() eq 'Community') { $lt{'nav'} = &mt('Community Contents'); } my $warnmsg; if ($arrow_dir eq 'forward') { $warnmsg = &mt('As all folders and sequences ' .'following the current resource were empty, ' .'you have now reached the end of the course.'); } elsif ($arrow_dir eq 'back') { $warnmsg = &mt('As all folders and sequences ' .'preceding the current resource were empty, ' .'you have now reached the beginning of the course.'); } my $start_page= &Apache::loncommon::start_page('Empty Folder/Sequence'); my $end_page= &Apache::loncommon::end_page(); $r->print(<$lt{'nere'}

$warnmsg

$end_page ENDNONE } else { &viewmap($r,$requrl); } return OK; } } 1; __END__ =head1 NAME Apache::lonsequence =head1 SYNOPSIS Handler for showing sequence objects of educational resources. This is part of the LearningOnline Network with CAPA project described at http://www.lon-capa.org. =head1 SUBROUTINES =over =item handler() =item viewmap() =item attemptread() =item mapread() =item start_fresh_session() =back =cut