--- loncom/interface/londocs.pm 2020/01/16 15:21:23 1.484.2.72.2.7 +++ loncom/interface/londocs.pm 2020/03/12 07:40:51 1.484.2.88 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.484.2.72.2.7 2020/01/16 15:21:23 raeburn Exp $ +# $Id: londocs.pm,v 1.484.2.88 2020/03/12 07:40:51 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -43,7 +43,6 @@ use Apache::lonnavdisplay(); use Apache::lonextresedit(); use Apache::lontemplate(); use Apache::lonsimplepage(); -use Apache::loncourserespicker(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -623,7 +622,7 @@ sub recurse_html { } sub group_import { - my ($coursenum, $coursedom, $folder, $container, $caller, $ltitoolsref, @files) = @_; + my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_; my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap, %removeparam,$importuploaded,$fixuperrors); $allmaps = {}; @@ -652,112 +651,6 @@ sub group_import { } } if ($url) { - if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/ext\.tool)\:?(.*)$}) { - $url = $1; - my $marker = $2; - my $info = $3; - my ($toolid,%toolhash,%toolsettings); - my @extras = ('linktext','explanation','crslabel','crstitle'); - my @toolinfo = split(/:/,$info); - if ($residx) { - %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum); - $toolid = $toolsettings{'id'}; - } else { - $toolid = shift(@toolinfo); - } - $toolid =~ s/\D//g; - ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'}, - $toolhash{'linktext'},$toolhash{'explanation'}, - $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo; - foreach my $item (@extras) { - $toolhash{$item} = &unescape($toolhash{$item}); - } - if (ref($ltitoolsref) eq 'HASH') { - my @deleted; - if (ref($ltitoolsref->{$toolid}) eq 'HASH') { - $toolhash{'id'} = $toolid; - if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') || - ($toolhash{'target'} eq 'window')) { - if ($toolhash{'target'} eq 'window') { - foreach my $item ('width','height') { - $toolhash{$item} =~ s/^\s+//; - $toolhash{$item} =~ s/\s+$//; - if ($toolhash{$item} =~ /\D/) { - delete($toolhash{$item}); - if ($residx) { - if ($toolsettings{$item}) { - push(@deleted,$item); - } - } - } - } - } - } elsif ($residx) { - $toolhash{'target'} = $toolsettings{'target'}; - if ($toolhash{'target'} eq 'window') { - foreach my $item ('width','height') { - $toolhash{$item} = $toolsettings{$item}; - } - } - } elsif (ref($ltitoolsref->{$toolid}->{'display'}) eq 'HASH') { - $toolhash{'target'} = $ltitoolsref->{$toolid}->{'display'}->{'target'}; - if ($toolhash{'target'} eq 'window') { - $toolhash{'width'} = $ltitoolsref->{$toolid}->{'display'}->{'width'}; - $toolhash{'height'} = $ltitoolsref->{$toolid}->{'display'}->{'height'}; - } - } - if ($toolhash{'target'} eq 'iframe') { - foreach my $item ('width','height','linktext','explanation') { - delete($toolhash{$item}); - if ($residx) { - if ($toolsettings{$item}) { - push(@deleted,$item); - } - } - } - } elsif ($toolhash{'target'} eq 'tab') { - foreach my $item ('width','height') { - delete($toolhash{$item}); - if ($residx) { - if ($toolsettings{$item}) { - push(@deleted,$item); - } - } - } - } - if (ref($ltitoolsref->{$toolid}->{'crsconf'}) eq 'HASH') { - foreach my $item ('label','title','linktext','explanation') { - my $crsitem; - if (($item eq 'label') || ($item eq 'title')) { - $crsitem = 'crs'.$item; - } else { - $crsitem = $item; - } - if ($ltitoolsref->{$toolid}->{'crsconf'}->{$item}) { - $toolhash{$crsitem} =~ s/^\s+//; - $toolhash{$crsitem} =~ s/\s+$//; - if ($toolhash{$crsitem} eq '') { - delete($toolhash{$crsitem}); - } - } else { - delete($toolhash{$crsitem}); - } - if (($residx) && (exists($toolsettings{$crsitem}))) { - unless (exists($toolhash{$crsitem})) { - push(@deleted,$crsitem); - } - } - } - } - my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum); - if ($putres eq 'ok') { - if (@deleted) { - &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum); - } - } - } - } - } if (($caller eq 'londocs') && ($folder =~ /^default/)) { if (($url =~ /\.(page|sequence)$/) && (!$donechk)) { @@ -769,8 +662,8 @@ sub group_import { $donechk = 1; } if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) { - &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap, - \%removeparam,\%addedmaps,\%hierarchy,\%titles,$allmaps); + &contained_map_check($url,$folder,\%removefrommap,\%removeparam, + \%addedmaps,\%hierarchy,\%titles,$allmaps); $importuploaded = 1; } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) { next if ($allmaps->{$url}); @@ -941,7 +834,7 @@ sub docs_change_log { '// '."\n". @@ -1166,29 +1059,47 @@ sub update_paste_buffer { # Construct identifiers for current contents of user's paste buffer if (@currpaste) { foreach my $suffix (@currpaste) { - my $cid = $env{'docs.markedcopy_crs_'.$suffix}; - my $url = $env{'docs.markedcopy_url_'.$suffix}; - if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && - ($url ne '')) { - $pasteurls{$cid.'_'.$url} = 1; - } + my $cid = $env{'docs.markedcopy_crs_'.$suffix}; + my $url = $env{'docs.markedcopy_url_'.$suffix}; + my $mapidx = $env{'docs.markedcopy_map_'.$suffix}; + if (($cid =~ /^$match_domain(?:_)$match_courseid$/) && + ($url ne '')) { + if ($url eq '/res/lib/templates/simpleproblem.problem') { + $pasteurls{$cid.'_'.$mapidx} = 1; + } elsif ($url =~ m{^/res/$match_domain/$match_username/}) { + $pasteurls{$url} = 1; + } else { + $pasteurls{$cid.'_'.$url} = 1; + } + } } } # Mark items for copying (skip any items already in user's paste buffer) my %addtoenv; - + + my @pathitems = split(/\&/,$env{'form.folderpath'}); + my @folderconf = split(/\:/,$pathitems[-1]); + my $ispage = $folderconf[5]; + foreach my $item (@possibles) { my ($orderidx,$cmd) = split(/:/,$item); next if ($orderidx =~ /\D/); next unless (($cmd eq 'cut') || ($cmd eq 'copy') || ($cmd eq 'remove')); + my $mapidx = $folder.':'.$orderidx.':'.$ispage; my ($title,$url)=split(':',$LONCAPA::map::resources[$orderidx]); my %denied = &action_restrictions($coursenum,$coursedom, &LONCAPA::map::qtescape($url), $env{'form.folderpath'},\%curr_groups); next if ($denied{'copy'}); $url=~s{http(:|:)//https(:|:)//}{https$2//}; - next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url})); + if ($url eq '/res/lib/templates/simpleproblem.problem') { + next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx})); + } elsif ($url =~ m{^/res/$match_domain/$match_username/}) { + next if (exists($pasteurls{$url})); + } else { + next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url})); + } my ($suffix,$errortxt,$locknotfreed) = &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste'); if ($suffix ne '') { @@ -1207,7 +1118,7 @@ sub update_paste_buffer { $addtoenv{'docs.markedcopy_url_'.$suffix} = $url, $addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd, $addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'}; - + $addtoenv{'docs.markedcopy_map_'.$suffix} = $mapidx; if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) { my $prefix = $1; my $subdir =$2; @@ -1215,8 +1126,8 @@ sub update_paste_buffer { $subdir = $prefix; } my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps); - &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap, - \%removeparam,\%addedmaps,\%hierarchy,\%titles,\%allmaps); + &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps, + \%hierarchy,\%titles,\%allmaps); if (ref($hierarchy{$url}) eq 'HASH') { my ($nested,$nestednames); &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames); @@ -1285,16 +1196,15 @@ sub print_paste_buffer { next if ($suffix =~ /\D/); my $cid = $env{'docs.markedcopy_crs_'.$suffix}; my $url = $env{'docs.markedcopy_url_'.$suffix}; + my $mapidx = $env{'docs.markedcopy_map_'.$suffix}; if (($cid =~ /^$match_domain\_$match_courseid$/) && ($url ne '')) { $clipboardcount ++; my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent, - $canpaste,$nopaste,$othercrs,$areachange,$is_exttool); + $canpaste,$nopaste,$othercrs,$areachange); my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1]; if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { $is_external = 1; - } elsif ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$}) { - $is_exttool = 1; } if ($folder =~ /^supplemental/) { $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix}); @@ -1327,34 +1237,26 @@ sub print_paste_buffer { $is_uploaded_map = 1; } } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) || - ($url =~ m{^/adm/($match_domain)/($match_username)/\d+/(bulletinboard|smppg|ext\.tool)$})) { + ($url =~ m{^/adm/($match_domain)/($match_username)/\d+/(bulletinboard|smppg)$})) { if ($cid ne $env{'request.course.id'}) { my ($srcdom,$srcnum) = split(/_/,$cid); if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { - if (($is_exttool) && ($srcdom ne $coursedom)) { - $canpaste = 0; - $nopaste = &mt('Paste from another domain unavailable.'); - } else { - $othercrs = '
'.&mt('(from another course)'); - } + $othercrs = '
'.&mt('(from another course)'); } else { $canpaste = 0; $nopaste = &mt('Paste from another course unavailable.'); } } } - } - if ($canpaste) { - push(@pasteable,$suffix); + if ($canpaste) { + push(@pasteable,$suffix); + } } my $buffer; - if ($is_external) { + if ($is_external) { $buffer = &mt('External Resource').': '. &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('. &LONCAPA::map::qtescape($url).')'; - } elsif ($is_exttool) { - $buffer = &mt('External Tool').': '. - &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}); } else { my $icon = &Apache::loncommon::icon($extension); if ($extension eq 'sequence' && @@ -1410,7 +1312,7 @@ sub print_paste_buffer { } $buttons = ''.(' 'x2); } - $buttons .= ''.(' 'x2); + $buttons .= ''.(' 'x2); if ($clipboardcount > 1) { $buttons .= ''.(' 'x20).''.(' 'x2). @@ -1511,8 +1413,7 @@ sub supp_pasteable { (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) || ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) || ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) || - ($url =~ m{^/public/$match_domain/$match_courseid/syllabus}) || - ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$})) { + ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) { return 1; } return; @@ -1634,12 +1535,13 @@ sub do_paste_from_buffer { return(); } - my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%notindom,%duplicate, - %prefixchg,%srcdom,%srcnum,%marktomove,$save_err,$lockerrors,$allresult); + my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate, + %prefixchg,%srcdom,%srcnum,%srcmapidx,%marktomove,$save_err,$lockerrors,$allresult); foreach my $suffix (@topaste) { my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix}); my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix}); + my $mapidx=&LONCAPA::map::qtescape($env{'docs.markedcopy_map_'.$suffix}); # Supplemental content may only include certain types of content # Early out if pasted content is not supported in Supplemental area if ($folder =~ /^supplemental/) { @@ -1661,7 +1563,8 @@ sub do_paste_from_buffer { } $srcdom{$suffix} = $srcd; $srcnum{$suffix} = $srcn; - } elsif ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$}) { + } elsif (($url =~ m{^/res/lib/templates/\w+\.problem$}) || + ($url =~ m{^/adm/$match_domain/$match_username/\d+/(bulletinboard|smppg)$})) { my ($srcd,$srcn) = split(/_/,$cid); # When paste buffer was populated using an active role in a different course # check for mdc privilege in the course from which the resource was pasted @@ -1671,15 +1574,10 @@ sub do_paste_from_buffer { next; } } -# When buffer was populated using an active role in a different course -# disallow pasting of External Tool if course is in a different domain. - if ($srcd ne $coursedom) { - $notindom{$suffix} = 1; - next; - } $srcdom{$suffix} = $srcd; $srcnum{$suffix} = $srcn; } + $srcmapidx{$suffix} = $mapidx; push(@dopaste,$suffix); if ($url=~/\.(page|sequence)$/) { $is_map{$suffix} = 1; @@ -1729,7 +1627,6 @@ sub do_paste_from_buffer { %msgs = &Apache::lonlocal::texthash ( notinsupp => 'Paste failed: content type is not supported within Supplemental Content', notincrs => 'Paste failed: Item is from a different course which you do not have rights to edit.', - notindom => 'Paste failed: Item is an external tool from a course in a different donain.', duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.', ); @@ -1758,21 +1655,14 @@ sub do_paste_from_buffer { # Retrieve information about all course maps in main content area my $allmaps = {}; - if ($folder =~ /^default/) { - $allmaps = - &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, - $env{"course.$env{'request.course.id'}.home"}, - $env{'request.course.id'}); - } - - my (@toclear,%mapurls,%lockerrs,%msgerrs,%results); + my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk); # Loop over the items to paste foreach my $suffix (@dopaste) { # Maps need to be copied first my (%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies, %dbcopies,%zombies,%params,%docmoves,%mapmoves,%mapchanges,%newsubdir, - %newurls,%tomove); + %newurls,%tomove,%resdatacopy); if (ref($marktomove{$suffix}) eq 'ARRAY') { map { $tomove{$_} = 1; } @{$marktomove{$suffix}}; } @@ -1783,9 +1673,15 @@ sub do_paste_from_buffer { if ($is_map{$suffix}) { # If pasting a map, check if map contains other maps my (%hierarchy,%titles); - &contained_map_check($url,$folder,$coursenum,$coursedom, - \%removefrommap,\%removeparam,\%addedmaps, - \%hierarchy,\%titles,$allmaps); + if (($folder =~ /^default/) && (!$donechk)) { + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $env{"course.$env{'request.course.id'}.home"}, + $env{'request.course.id'}); + $donechk = 1; + } + &contained_map_check($url,$folder,\%removefrommap,\%removeparam, + \%addedmaps,\%hierarchy,\%titles,$allmaps); if ($url=~ m{^/uploaded/}) { my $newurl; unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') { @@ -1815,7 +1711,7 @@ sub do_paste_from_buffer { \%retitles,\%copies,\%dbcopies, \%zombies,\%params,\%mapmoves, \%mapchanges,\%tomove,\%newsubdir, - \%newurls)) { + \%newurls,\%resdatacopy)) { $mapmoves{$url} = 1; } $url = $newurl; @@ -1824,7 +1720,7 @@ sub do_paste_from_buffer { $coursenum,$srcdom{$suffix},$srcnum{$suffix}, $allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies, \%zombies,\%params,\%mapmoves,\%mapchanges, - \%tomove,\%newsubdir,\%newurls); + \%tomove,\%newsubdir,\%newurls,\%resdatacopy); } } elsif ($url=~m {^/res/}) { # published map can only exist once, so remove from paste buffer when done @@ -1838,7 +1734,7 @@ sub do_paste_from_buffer { } } } - if ($url=~ m{/(ext\.tool)$}) { + if ($url=~ m{/(bulletinboard|smppg)$}) { my $prefix = $1; my $fromothercrs; #need to copy the db contents to a new one, unless this is a move. @@ -1846,7 +1742,7 @@ sub do_paste_from_buffer { src => $url, cdom => $coursedom, cnum => $coursenum, - ); + ); if (($srcdom{$suffix} =~ /^$match_domain$/) && ($srcnum{$suffix} =~ /^$match_courseid$/)) { unless (($srcdom{$suffix} eq $coursedom) && ($srcnum{$suffix} eq $coursenum)) { $fromothercrs = 1; @@ -1862,8 +1758,10 @@ sub do_paste_from_buffer { $url = $newurl; $title=&mt('Copy of').' '.$title; } else { - if ($prefix eq 'ext.tool') { - $msg = &mt('Paste failed: An error occurred when copying the external tool.').' '.$errtext; + if ($prefix eq 'smppg') { + $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext; + } elsif ($prefix eq 'bulletinboard') { + $msg = &mt('Paste failed: An error occurred when copying the discussion board.').' '.$errtext; } $results{$suffix} = $result; $msgerrs{$suffix} = $msg; @@ -1928,6 +1826,12 @@ sub do_paste_from_buffer { } } } + } elsif ($url =~ m{^/res/lib/templates/(\w+)\.problem$}) { + my $template = $1; + if ($newidx) { + ©_templated_files($url,$srcdom{$suffix},$srcnum{$suffix},$srcmapidx{$suffix}, + $coursedom,$coursenum,$template,$newidx,"$folder.$container"); + } } $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url). ':'.$ext.':normal:res'; @@ -1941,7 +1845,8 @@ sub do_paste_from_buffer { } } -# Apply any changes to maps, or copy dependencies for uploaded HTML pages +# Apply any changes to maps, or copy dependencies for uploaded HTML pages, or update +# resourcedata for simpleproblems copied from another course unless ($allresult eq 'fail') { my %updated = ( rewrites => \%rewrites, @@ -1949,6 +1854,7 @@ sub do_paste_from_buffer { removefrommap => \%removefrommap, removeparam => \%removeparam, dbcopies => \%dbcopies, + resdatacopy => \%resdatacopy, retitles => \%retitles, ); my %info = ( @@ -2115,11 +2021,8 @@ sub dbcopy { my ($url,$result,$errtext); if (ref($dbref) eq 'HASH') { $url = $dbref->{'src'}; - if ($url =~ m{/(smppg|bulletinboard|ext\.tool)$}) { + if ($url =~ m{/(smppg|bulletinboard)$}) { my $prefix = $1; - if ($prefix eq 'ext.tool') { - $prefix = 'exttool'; - } if (($dbref->{'cdom'} =~ /^$match_domain$/) && ($dbref->{'cnum'} =~ /^$match_courseid$/)) { my $db_name; @@ -2130,8 +2033,6 @@ sub dbcopy { &Apache::lonsimplepage::get_db_name($url,$marker, $dbref->{'cdom'}, $dbref->{'cnum'}); - } elsif ($dbref->{'src'} =~ m{/ext\.tool$}) { - $db_name = 'exttool_'.$marker; } else { $db_name = 'bulletinpage_'.$marker; } @@ -2142,8 +2043,6 @@ sub dbcopy { if (!$suffix) { if ($prefix eq 'smppg') { $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url); - } elsif ($prefix eq 'exttool') { - $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying an external tool [_1].',$url); } else { $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a discussion board [_1].',$url); } @@ -2177,7 +2076,7 @@ sub dbcopy { $result=&Apache::lonnet::put($db_name,\%contents, $coursedom,$coursenum); if ($result eq 'ok') { - $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x; + $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x; } } if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) { @@ -2187,9 +2086,6 @@ sub dbcopy { if ($prefix eq 'smppg') { $lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional simple pages in this course.'); - } elsif ($prefix eq 'exttool') { - $lockerrorsref->{$prefix} .= - ' '.&mt('This will prevent addition of more external tools to this course.'); } else { $lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional discussion boards in this course.'); } @@ -2215,6 +2111,97 @@ sub dbcopy { return ($url,$result,$errtext); } +sub copy_templated_files { + my ($srcurl,$srcdom,$srcnum,$srcmapinfo,$coursedom,$coursenum,$template,$newidx,$newmapname) = @_; + my ($srcfolder,$srcid,$srcwaspage) = split(/:/,$srcmapinfo); + my $srccontainer = 'sequence'; + if ($srcwaspage) { + $srccontainer = 'page'; + } + my $srcsymb = "uploaded/$srcdom/$srcnum/$srcfolder.$srccontainer". + '___'.$srcid.'___'.&Apache::lonnet::declutter($srcurl); + my $srcprefix = $srcdom.'_'.$srcnum.'.'.$srcsymb; + my %srcparms=&Apache::lonnet::dump('resourcedata',$srcdom,$srcnum,$srcprefix); + my $newsymb = "uploaded/$coursedom/$coursenum/$newmapname".'___'.$newidx.'___lib/templates/'. + $template.'.problem'; + my $newprefix = $coursedom.'_'.$coursenum.'.'.$newsymb; + if ($template eq 'simpleproblem') { + $srcprefix .= '.0.'; + my $weightprefix = $newprefix; + $newprefix .= '.0.'; + my @simpleprobqtypes = qw(radio option string essay numerical); + my $qtype=$srcparms{$srcprefix.'questiontype'}; + if (grep(/^\Q$qtype\E$/,@simpleprobqtypes)) { + my %newdata = ( + $newprefix.'questiontype' => $qtype, + ); + foreach my $type (@simpleprobqtypes) { + if ($type eq $qtype) { + $newdata{"$weightprefix.$type.weight"}=1; + } else { + $newdata{"$weightprefix.$type.weight"}=0; + } + } + $newdata{$newprefix.'hiddenparts'} = '!'.$qtype; + $newdata{$newprefix.'questiontext'} = $srcparms{$srcprefix.'questiontext'}; + $newdata{$newprefix.'hinttext'} = $srcparms{$srcprefix.'hinttext'}; + if ($qtype eq 'numerical') { + $newdata{$newprefix.'numericalscript'} = $srcparms{$srcprefix.'numericalscript'}; + $newdata{$newprefix.'numericalanswer'} = $srcparms{$srcprefix.'numericalanswer'}; + $newdata{$newprefix.'numericaltolerance'} = $srcparms{$srcprefix.'numericaltolerance'}; + $newdata{$newprefix.'numericalsigfigs'} = $srcparms{$srcprefix.'numericalsigfigs'}; + } elsif (($qtype eq 'option') || ($qtype eq 'radio')) { + my $maxfoils=$srcparms{$srcprefix.'maxfoils'}; + unless (defined($maxfoils)) { $maxfoils=10; } + unless ($maxfoils=~/^\d+$/) { $maxfoils=10; } + if ($maxfoils<=0) { $maxfoils=10; } + my $randomize=$srcparms{$srcprefix.'randomize'}; + unless (defined($randomize)) { $randomize='yes'; } + unless ($randomize eq 'no') { $randomize='yes'; } + $newdata{$newprefix.'maxfoils'} = $maxfoils; + $newdata{$newprefix.'randomize'} = $randomize; + if ($qtype eq 'option') { + $newdata{$newprefix.'options'} = $srcparms{$srcprefix.'options'}; + } + for (my $i=1; $i<=10; $i++) { + $newdata{$newprefix.'value'.$i} = $srcparms{$srcprefix.'value'.$i}; + $newdata{$newprefix.'position'.$i} = $srcparms{$srcprefix.'position'.$i}; + $newdata{$newprefix.'text'.$i} = $srcparms{$srcprefix.'text'.$i}; + } + + } elsif (($qtype eq 'option') || ($qtype eq 'radio')) { + my $maxfoils=$srcparms{$srcprefix.'maxfoils'}; + unless (defined($maxfoils)) { $maxfoils=10; } + unless ($maxfoils=~/^\d+$/) { $maxfoils=10; } + if ($maxfoils<=0) { $maxfoils=10; } + my $randomize=$srcparms{$srcprefix.'randomize'}; + unless (defined($randomize)) { $randomize='yes'; } + unless ($randomize eq 'no') { $randomize='yes'; } + $newdata{$newprefix.'maxfoils'} = $maxfoils; + $newdata{$newprefix.'randomize'} = $randomize; + if ($qtype eq 'option') { + $newdata{$newprefix.'options'} = $srcparms{$srcprefix.'options'}; + } + for (my $i=1; $i<=10; $i++) { + $newdata{$newprefix.'value'.$i} = $srcparms{$srcprefix.'value'.$i}; + $newdata{$newprefix.'position'.$i} = $srcparms{$srcprefix.'position'.$i}; + $newdata{$newprefix.'text'.$i} = $srcparms{$srcprefix.'text'.$i}; + } + } elsif ($qtype eq 'string') { + $newdata{$newprefix.'stringanswer'} = $srcparms{$srcprefix.'stringanswer'}; + $newdata{$newprefix.'stringtype'} = $srcparms{$srcprefix.'stringtype'}; + } + if (keys(%newdata)) { + my $putres = &Apache::lonnet::cput('resourcedata',\%newdata,$coursedom, + $coursenum); + if ($putres eq 'ok') { + &Apache::lonnet::devalidatecourseresdata($coursenum,$coursedom); + } + } + } + } +} + sub uniqueness_check { my ($newurl) = @_; my $unique = 1; @@ -2230,8 +2217,8 @@ sub uniqueness_check { } sub contained_map_check { - my ($url,$folder,$coursenum,$coursedom,$removefrommap,$removeparam,$addedmaps, - $hierarchy,$titles,$allmaps) = @_; + my ($url,$folder,$removefrommap,$removeparam,$addedmaps,$hierarchy,$titles, + $allmaps) = @_; my $content = &Apache::lonnet::getfile($url); unless ($content eq '-1') { my $parser = HTML::TokeParser->new(\$content); @@ -2260,8 +2247,7 @@ sub contained_map_check { $addedmaps->{$ressrc} = [$url]; } } - &contained_map_check($ressrc,$folder,$coursenum,$coursedom, - $removefrommap,$removeparam, + &contained_map_check($ressrc,$folder,$removefrommap,$removeparam, $addedmaps,$hierarchy,$titles,$allmaps); } } elsif ($token->[1] eq 'param') { @@ -2281,7 +2267,7 @@ sub contained_map_check { sub url_paste_fixups { my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps, $rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves, - $mapchanges,$tomove,$newsubdir,$newurls) = @_; + $mapchanges,$tomove,$newsubdir,$newurls,$resdatacopy) = @_; my $checktitle; if (($prefixchg) && ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) { @@ -2330,7 +2316,7 @@ sub url_paste_fixups { $srcdom,$srcnum,$allmaps,$rewrites, $retitles,$copies,$dbcopies,$zombies, $params,$mapmoves,$mapchanges,$tomove, - $newsubdir,$newurls); + $newsubdir,$newurls,$resdatacopy); next; } else { ($newurl,my $error) = @@ -2354,7 +2340,7 @@ sub url_paste_fixups { $cnum,$srcdom,$srcnum,$allmaps, $rewrites,$retitles,$copies,$dbcopies, $zombies,$params,$mapmoves,$mapchanges, - $tomove,$newsubdir,$newurls)) { + $tomove,$newsubdir,$newurls,$resdatacopy)) { $mapmoves->{$ressrc} = 1; } $changed = 1; @@ -2383,6 +2369,12 @@ sub url_paste_fixups { $dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum; $changed = 1; } + } elsif ($ressrc eq '/res/lib/templates/simpleproblem.problem') { + if (($fromcdom ne $cdom) || ($fromcnum ne $cnum)) { + $resdatacopy->{$oldurl}{$id}{'src'} = $ressrc; + $resdatacopy->{$oldurl}{$id}{'cdom'} = $fromcdom; + $resdatacopy->{$oldurl}{$id}{'cnum'} = $fromcnum; + } } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) { next if ($skip); my $srcdom = $1; @@ -2414,7 +2406,7 @@ sub apply_fixups { $oldurl,$url,$caller) = @_; my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles, %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs, - %lockerrors,$lockmsg); + %resdatacopy,%lockerrors,$lockmsg); if (ref($updated) eq 'HASH') { if (ref($updated->{'rewrites'}) eq 'HASH') { %rewrites = %{$updated->{'rewrites'}}; @@ -2434,6 +2426,9 @@ sub apply_fixups { if (ref($updated->{'retitles'}) eq 'HASH') { %retitles = %{$updated->{'retitles'}}; } + if (ref($updated->{'resdatacopy'}) eq 'HASH') { + %resdatacopy = %{$updated->{'resdatacopy'}}; + } } if (ref($info) eq 'HASH') { if (ref($info->{'newsubdir'}) eq 'HASH') { @@ -2584,6 +2579,36 @@ sub apply_fixups { } } } + if (ref($resdatacopy{$key}) eq 'HASH') { + my ($gotnewmapname,$newmapname,$srcfolder,$srccontainer); + foreach my $idx (keys(%{$resdatacopy{$key}})) { + if (ref($resdatacopy{$key}{$idx}) eq 'HASH') { + my $srcurl = $resdatacopy{$key}{$idx}{'src'}; + if ($srcurl =~ m{^/res/lib/templates/(\w+)\.problem$}) { + my $template = $1; + if (($resdatacopy{$key}{$idx}{'cdom'} =~ /^$match_domain$/) && + ($resdatacopy{$key}{$idx}{'cnum'} =~ /^$match_courseid$/)) { + my $srcdom = $resdatacopy{$key}{$idx}{'cdom'}; + my $srcnum = $resdatacopy{$key}{$idx}{'cnum'}; + unless ($gotnewmapname) { + ($newmapname) = ($key =~ m{/([^/]+)$}); + ($srcfolder,$srccontainer) = split(/\./,$newmapname); + if ($newsubdir{$key}) { + $newmapname =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; + } + $gotnewmapname = 1; + } + my $srcmapinfo = $srcfolder.':'.$idx; + if ($srccontainer eq 'page') { + $srcmapinfo .= ':1'; + } + ©_templated_files($srcurl,$srcdom,$srcnum,$srcmapinfo,$cdom, + $cnum,$template,$idx,$newmapname); + } + } + } + } + } if (ref($params{$key}) eq 'HASH') { %currparam = %{$params{$key}}; } @@ -2911,8 +2936,8 @@ sub handle_edit_cmd { sub editor { my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype, - $supplementalflag,$orderhash,$iconpath,$pathitem,$ltitoolsref, - $canedit,$navmapref,$hiddentop)=@_; + $supplementalflag,$orderhash,$iconpath,$pathitem,$canedit, + $hostname,$navmapref,$hiddentop)=@_; my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container); if ($allowed) { (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain, @@ -3123,17 +3148,6 @@ sub editor { } else { return $errortxt; } - } elsif ($url =~ m{^/adm/$coursedom/$coursenum/new/ext\.tool}) { - my ($suffix,$errortxt,$locknotfreed) = - &new_timebased_suffix($coursedom,$coursenum,'exttool'); - if ($locknotfreed) { - $r->print($locknotfreed); - } - if ($suffix) { - $url =~ s{^(/adm/$coursedom/$coursenum)/new}{$1/$suffix}; - } else { - return $errortxt; - } } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) { if ($supplementalflag) { next unless ($1 eq 'supplemental'); @@ -3156,7 +3170,7 @@ sub editor { } ($errtext,$fatal,my $fixuperrors) = &group_import($coursenum, $coursedom, $folder,$container, - 'londocs',$ltitoolsref,@imports); + 'londocs',@imports); return $errtext if ($fatal); if ($fixuperrors) { $r->print($fixuperrors); @@ -3242,8 +3256,8 @@ sub editor { $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, $coursenum,$coursedom,$crstype, $pathitem,$supplementalflag,$container, - \%filters,\%curr_groups,$ltitoolsref,$canedit, - $isencrypted,$navmapref); + \%filters,\%curr_groups,$canedit, + $isencrypted,$navmapref,$hostname); $idx++; $shown++; } @@ -3622,7 +3636,7 @@ sub is_supplemental_title { sub entryline { my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom, $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups, - $ltitoolsref,$canedit,$isencrypted,$navmapref)=@_; + $canedit,$isencrypted,$navmapref,$hostname)=@_; my ($foldertitle,$renametitle,$oldtitle); if (&is_supplemental_title($title)) { ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); @@ -3719,7 +3733,6 @@ END 'rn' => 'Rename', 'cp' => 'Copy', 'ex' => 'External Resource', - 'et' => 'External Tool', 'ed' => 'Edit', 'pr' => 'Preview', 'sv' => 'Save', @@ -3739,7 +3752,6 @@ END |/aboutme$ |/navmaps$ |/bulletinboard$ - |/ext\.tool$ |\.html$)}x) || $isexternal) { $skip_confirm = 1; @@ -3874,11 +3886,19 @@ END my ($editlink,$extresform,$anchor,$hiddenres,$nomodal); my $orig_url = $url; $orig_url=~s{http(:|:)//https(:|:)//}{https$2//}; - $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; + if ($container eq 'page') { + $url=~s{^http(|s)(:|:)//}{/ext/}; + } else { + $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; + } if (!$supplementalflag && $residx && $symb) { if ((!$isfolder) && (!$ispage)) { (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); - $url=&Apache::lonnet::clutter($url); + if (($url =~ m{^ext/}) && ($container eq 'page')) { + $url=&Apache::lonnet::clutter_with_no_wrapper($url); + } else { + $url=&Apache::lonnet::clutter($url); + } if ($url=~/^\/*uploaded\//) { $url=~/\.(\w+)$/; my $embstyle=&Apache::loncommon::fileembstyle($1); @@ -3892,29 +3912,27 @@ END } elsif ($url=~m{^(|/adm/wrapper)/ext/([^#]+)}) { my $wrapped = $1; my $exturl = $2; - if ($wrapped eq '') { + if (($wrapped eq '') && ($container ne 'page')) { $url='/adm/wrapper'.$url; } if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) { $nomodal = 1; } - } elsif ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) { - $url='/adm/wrapper'.$url; } elsif ($url eq "/public/$coursedom/$coursenum/syllabus") { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { + unless (&Apache::lonnet::uses_sts()) { + $url .= '?usehttp=1'; + } $nomodal = 1; } } if (&Apache::lonnet::symbverify($symb,$url)) { my $shownsymb = $symb; if ($isexternal) { - if ($url =~ /^([^#]+)#([^#]+)$/) { - $url = $1; - $anchor = $2; - if ($symb =~ m{^([^#]+)\Q#$anchor\E$}) { - $shownsymb = $1.&escape('#').$anchor; - } + $url =~ s/\#[^#]+$//; + if ($container eq 'page') { + $url = &Apache::lonnet::clutter($url); } } unless ($env{'request.role.adv'}) { @@ -3968,12 +3986,24 @@ END $url = $1; $anchor = $2; if (($url =~ m{^(|/adm/wrapper)/ext/(?!https:)}) && ($ENV{'SERVER_PORT'} == 443)) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $url = 'http://'.$hostname.$url; + } + $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1'; + } $nomodal = 1; } } } elsif ($url =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $url = 'http://'.$hostname.$url; + } + $url .= (($url =~ /\?/) ? '&':'?').'usehttp=1'; + } $nomodal = 1; } } @@ -4064,17 +4094,12 @@ $form_common."\n". $form_end; } } elsif ($supplementalflag && !$allowed) { - my $isexttool; - if ($url=~m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) { - $url='/adm/wrapper'.$url; - $isexttool = 1; - } $url .= ($url =~ /\?/) ? '&':'?'; $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"'); if ($title) { $url .= '&title='.&HTML::Entities::encode($renametitle,'<>&"'); } - if ((($isexternal) || ($isexttool)) && $orderidx) { + if ($isexternal && $orderidx) { $url .= '&idx='.$orderidx; } if ($anchor ne '') { @@ -4088,13 +4113,7 @@ $form_end; if ($isexternal) { ($editlink,$extresform) = &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem, - undef,undef,undef,undef,undef,undef, - undef,$disabled); - } elsif ($orig_url =~ m{^/adm/$coursedom/$coursenum/\d+/ext\.tool$}) { - ($editlink,$extresform) = - &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem, - undef,undef,undef,'tool',$coursedom, - $coursenum,$ltitoolsref,$disabled); + undef,undef,undef,$disabled); } elsif (!$isfolder && !$ispage) { my ($cfile,$home,$switchserver,$forceedit,$forceview) = &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url); @@ -4109,7 +4128,8 @@ $form_end; $forceedit, undef,$symb, &escape($env{'form.folderpath'}), - $renametitle,'','',1,$suppanchor); + $renametitle,$hostname, + '','',1,$suppanchor); if ($jscall) { $editlink = ''.&mt('Edit').' '."\n"; @@ -4137,8 +4157,13 @@ $form_end; $anchor = '#'.&HTML::Entities::encode($anchor,'"<>&'); } } - $link = &js_escape($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes'. - (($anchor ne '')?$anchor:'')); + + if ((!$supplementalflag) && ($nomodal) && ($hostname ne '')) { + $link = 'http://'.$hostname.$url; + } else { + $link = $url; + } + $link = &js_escape($link.(($url=~/\?/)?'&':'?').'inhibitmenu=yes'.$anchor); if ($nomodal) { $line.=''. ''; @@ -4218,9 +4243,11 @@ sub action_restrictions { if ($url=~ m{^/res/.+\.(page|sequence)$}) { # no copy for published maps $denied{'copy'} = 1; - } elsif ($url=~m{^/res/lib/templates/}) { - $denied{'copy'} = 1; - $denied{'cut'} = 1; + } elsif ($url=~m{^/res/lib/templates/([^/]+)\.problem$}) { + unless ($1 eq 'simpleproblem') { + $denied{'copy'} = 1; + } + $denied{'cut'} = 1; } elsif ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") { if ($folderpath =~ /^default&[^\&]+$/) { if ((ref($currgroups) eq 'HASH') && (keys(%{$currgroups}) > 0)) { @@ -4297,8 +4324,6 @@ sub new_timebased_suffix { $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.'); } elsif ($type eq 'smppg') { $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.'); - } elsif ($type eq 'exttool') { - $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new external tool.'); } else { $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new discussion board.'); } @@ -4327,9 +4352,6 @@ sub new_timebased_suffix { } elsif ($type eq 'smppg') { $locknotfreed .= &mt('This will prevent creation of additional simple pages in this course.'); - } elsif ($type eq 'exttool') { - $locknotfreed .= - &mt('This will prevent creation of additional external tools in this course.'); } else { $locknotfreed .= &mt('This will prevent creation of additional discussion boards in this course.'); @@ -4380,7 +4402,7 @@ sub untiehash { sub checkonthis { - my ($r,$url,$level,$title)=@_; + my ($r,$url,$level,$title,$checkstale)=@_; $url=&unescape($url); $alreadyseen{$url}=1; $r->rflush(); @@ -4395,10 +4417,22 @@ sub checkonthis { $r->print(''. ($title?$title:$url).' '); if ($url=~/^\/res\//) { + my $updated; + if (($checkstale) && ($url !~ m{^/res/lib/templates/}) && + ($url !~ /\.\d+\.\w+$/)) { + $updated = &Apache::lonnet::remove_stale_resfile($url); + } my $result=&Apache::lonnet::repcopy( &Apache::lonnet::filelocation('',$url)); if ($result eq 'ok') { $r->print(''.&mt('ok').''); + if ($updated) { + $r->print('
'); + for (my $i=0;$i<=$level*5;$i++) { + $r->print(' '); + } + $r->print('- '.&mt('Outdated copy removed')); + } $r->rflush(); &Apache::lonnet::countacc($url); $url=~/\.(\w+)$/; @@ -4432,7 +4466,7 @@ sub checkonthis { &Apache::lonnet::metadata($url,'dependencies'); foreach my $dep (split(/\,/,$dependencies)) { if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) { - &checkonthis($r,$dep,$level+1); + &checkonthis($r,$dep,$level+1,'',$checkstale); } } } elsif ($result eq 'unavailable') { @@ -4446,6 +4480,9 @@ sub checkonthis { } else { $r->print(''.&mt('access denied').''); } + if (($updated) && ($result ne 'ok')) { + $r->print('
'.&mt('Outdated copy removed')); + } } } } @@ -4498,50 +4535,29 @@ sub list_symbs { $r->print(&endContentScreen()); } -sub short_urls { - my ($r,$canedit) = @_; +sub contentverifyform { + my ($r) = @_; my $crstype = &Apache::loncommon::course_type(); - my $formname = 'shortenurl'; - $r->print(&Apache::loncommon::start_page('Display/Set Shortened URLs')); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Shortened URLs')); + $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content')); $r->print(&startContentScreen('tools')); - my ($navmap,$errormsg) = - &Apache::loncourserespicker::get_navmap_object($crstype,'shorturls'); - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my (%maps,%resources,%titles); - if (!ref($navmap)) { - $r->print($errormsg. - &endContentScreen()); - return ''; - } else { - $r->print('

'.&mt('Tiny URLs for deep-linking into course').'

'."\n"); - $r->rflush(); - my $readonly; - if ($canedit) { - my ($numnew,$errors) = &Apache::loncommon::make_short_symbs($cdom,$cnum,$navmap); - if ($numnew) { - $r->print('

'.&mt('Created [quant,_1,URL]',$numnew).'

'); - } - if ((ref($errors) eq 'ARRAY') && (@{$errors} > 0)) { - $r->print(&mt('The following errors occurred when processing your request to create shortened URLs:').'

'); - } - } else { - $readonly = 1; - } - my %currtiny = &Apache::lonnet::dump('tiny',$cdom,$cnum); - $r->print(&Apache::loncourserespicker::create_picker($navmap,'shorturls',$formname,$crstype,undef, - undef,undef,undef,undef,undef,\%currtiny,$readonly)); - } + $r->print('

'.&mt($crstype.' content verification').'

'); + $r->print('

'. + &mt('Include a check if files copied from elsewhere are up to date (will increase verification time)?'). + ' '. + ''.(' 'x2). + '

'. + ''. + ''. + '

'); $r->print(&endContentScreen()); + return; } sub verifycontent { - my ($r) = @_; + my ($r,$checkstale) = @_; my $crstype = &Apache::loncommon::course_type(); $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content')); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content')); @@ -4562,7 +4578,7 @@ sub verifycontent { } } if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) { - &checkonthis($r,$hash{$key},0,$hash{'title_'.$1}); + &checkonthis($r,$hash{$key},0,$hash{'title_'.$1},$checkstale); } } &untiehash(); @@ -4992,12 +5008,12 @@ sub handler { # # --------------------------------------------- Initialize help topics for this foreach my $topic ('Adding_Course_Doc','Main_Course_Documents', - 'Adding_External_Resource','Adding_External_Tool', - 'Navigate_Content','Adding_Folders','Docs_Overview', - 'Load_Map','Supplemental','Score_Upload_Form', - 'Adding_Pages','Importing_LON-CAPA_Resource', - 'Importing_IMS_Course','Uploading_From_Harddrive', - 'Course_Roster','Web_Page','Dropbox','Simple_Problem') { + 'Adding_External_Resource','Navigate_Content', + 'Adding_Folders','Docs_Overview', 'Load_Map', + 'Supplemental','Score_Upload_Form','Adding_Pages', + 'Importing_LON-CAPA_Resource','Importing_IMS_Course', + 'Uploading_From_Harddrive','Course_Roster','Web_Page', + 'Dropbox','Simple_Problem') { $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic); } # Composite help files @@ -5034,15 +5050,23 @@ sub handler { delete($env{'form.inhibitmenu'}); } } + if ($allowed && $env{'form.verify'}) { &init_breadcrumbs('verify','Verify Content','Docs_Verify_Content'); - &verifycontent($r); + if (!$canedit) { + &verifycontent($r); + } elsif (($env{'form.checkstale'} ne '') && ($env{'form.checkstale'} =~ /^\d$/)) { + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1&verify=1&checkstale=$env{'form.checkstale'}", + text=>'Results', + faq=>273, + bug=>'Instructor Interface'}); + &verifycontent($r,$env{'form.checkstale'}); + } else { + &contentverifyform($r); + } } elsif ($allowed && $env{'form.listsymbs'}) { &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); - } elsif ($allowed && $env{'form.shorturls'}) { - &init_breadcrumbs('shorturls','Set/Display Shortened URLs','Docs_Short_URLs'); - &short_urls($r,$canedit); } elsif ($allowed && $env{'form.docslog'}) { &init_breadcrumbs('docslog','Show Log'); my $folder = $env{'form.folder'}; @@ -5089,6 +5113,7 @@ sub handler { delete($env{'form.symb'}); } } + # standard=1: this is a "new-style" course with an uploaded map as top level # standard=2: this is a "old-style" course, and there is nothing we can do @@ -5149,7 +5174,6 @@ sub handler { my $container; my $containertag; my $pathitem; - my %ltitools; my $hiddentop; my $navmap; my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) }; @@ -5223,7 +5247,7 @@ sub handler { undef($env{'form.folderpath'}); } else { $folderurl = "uploaded/$coursedom/$coursenum/$folder"; - if ((split(/\:/,$pathitems[-1]))[4]) { + if ((split(/\:/,$pathitems[-1]))[5]) { $folderurl .= '.page'; } else { $folderurl .= '.sequence'; @@ -5327,14 +5351,13 @@ sub handler { } } my $tabidstr = join("','",@tabids); - %ltitools = &Apache::lonnet::get_domain_ltitools($coursedom); - my $posslti = keys(%ltitools); - $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti, - $canedit,\$navmap). + my $hostname = $r->hostname(); + $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum, + $canedit,$hostname,\$navmap). &history_tab_js(). &inject_data_js(). &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid). - &Apache::lonextresedit::extedit_javascript(\%ltitools); + &Apache::lonextresedit::extedit_javascript(); $addentries = { onload => "javascript:resize_scrollbox('contentscroll','1','1');", }; @@ -5350,7 +5373,8 @@ sub handler { .'// '."\n" - .''."\n"; + .''."\n" + .''."\n"; # Breadcrumbs &Apache::lonhtmlcommon::clear_breadcrumbs(); @@ -5469,8 +5493,6 @@ sub handler { 'impo' => 'Import', 'lnks' => 'Import from Stored Links', 'impm' => 'Import from Assembled Map', - 'extr' => 'External Resource', - 'extt' => 'External Tool', 'selm' => 'Select Map', 'load' => 'Load Map', 'newf' => 'New Folder', @@ -5502,7 +5524,8 @@ sub handler { 'er' => 'Editing rights unavailable for your current role.', ); # ----------------------------------------------------------------------------- - # Calculate free quota space for a user or course. + # Calculate free quota space for a user or course. A javascript function checks + # file size to determine if upload should be allowed. my $quotatype = 'unofficial'; if ($crstype eq 'Community') { $quotatype = 'community'; @@ -5536,7 +5559,8 @@ sub handler { my $fileupload=(< - + + FIUP my $checkbox=(<hostname(); if ($allowed) { my $folder=$env{'form.folder'}; @@ -5893,11 +5913,6 @@ NGFFORM my @importdoc = ( {''.$lt{extr}.''=>$extresourcesform} ); - if (keys(%ltitools)) { - push(@importdoc, - {''.$lt{extt}.''=>$exttoolform}, - ); - } unless ($container eq 'page') { push(@importdoc, {''.$lt{imsf}.''=>$imspform} @@ -5940,7 +5955,7 @@ unless ($container eq 'page') { unless (($supplementalflag || $toolsflag)) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, $supplementalflag,\%orderhash,$iconpath,$pathitem, - \%ltitools,$canedit,\$navmap,$hiddentop); + $canedit,$hostname,\$navmap,$hiddentop); undef($navmap); if ($error) { $r->print('

'.$error.'

'); @@ -5950,6 +5965,7 @@ unless ($container eq 'page') { &mark_hash_old(); } } + &changewarning($r,''); } } @@ -6008,13 +6024,8 @@ SNFFORM my $supextform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, $help{'Adding_External_Resource'}, - undef,undef,undef,undef,undef,undef, - $disabled); - my $supexttoolform = - &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, - $help{'Adding_External_Tool'}, - undef,undef,'tool',$coursedom, - $coursenum,\%ltitools,$disabled); + undef,undef,$disabled); + my $supnewsylform=(< @@ -6068,16 +6079,10 @@ my @specialdocs = ( ); my @supimportdoc = ( {''.$lt{extr}.'' - =>$supextform}); - if (keys(%ltitools)) { - push(@supimportdoc, - {''.$lt{extt}.'' - =>$supexttoolform}); - } - push(@supimportdoc, + =>$supextform}, {''.$lt{upl}.'' =>$supupdocform}, - ); + ); $supupdocform = &create_form_ul(&create_list_elements(@supimportdoc)); my %suporderhash = ( @@ -6088,7 +6093,7 @@ my %suporderhash = ( if ($supplementalflag) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, $supplementalflag,\%suporderhash,$iconpath,$pathitem, - \%ltitools,$canedit); + $canedit,$hostname); if ($error) { $r->print('

'.$error.'

'); } else { @@ -6108,7 +6113,7 @@ my %suporderhash = ( } } elsif ($supplementalflag) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,'',$iconpath,$pathitem); + $supplementalflag,'',$iconpath,$pathitem,'',$hostname); if ($error) { $r->print('

'.$error.'

'); } @@ -6308,7 +6313,6 @@ sub generate_admin_menu { 'vc' => 'Verify Content', 'cv' => 'Check/Set Resource Versions', 'ls' => 'List Resource Identifiers', - 'ct' => 'Display/Set Shortened URLs for Deep-linking', 'imse' => 'Export contents to IMS Archive', 'dcd' => "Copy $crstype Content to Authoring Space", ); @@ -6359,13 +6363,6 @@ sub generate_admin_menu { icon => 'symbs.png', linktitle => "List the unique identifier used for each resource instance in your $lc_crstype" }, - { linktext => $lt{'ct'}, - url => "javascript:injectData(document.courseverify,'dummy','shorturls','$lt{'ct'}')", - permission => 'F', - help => 'Docs_Short_URLs', - icon => 'shorturls.png', - linktitle => "Set shortened URLs for a resource or folder in your $lc_crstype for use in deep-linking" - }, ] }); if ($canedit) { @@ -6496,7 +6493,8 @@ END } sub editing_js { - my ($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,$canedit,$navmapref) = @_; + my ($udom,$uname,$supplementalflag,$coursedom,$coursenum, + $canedit,$hostname,$navmapref) = @_; my %js_lt = &Apache::lonlocal::texthash( p_mnf => 'Name of New Folder', t_mnf => 'New Folder', @@ -6575,6 +6573,26 @@ sub editing_js { $backtourl .= '?symb='. &HTML::Entities::encode($caller,'<>&"'); } + if ($backtourl =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { + if (($ENV{'SERVER_PORT'} == 443) && + ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } + } elsif ($backtourl =~ m{^/adm/wrapper/ext/(?!https:)}) { + if (($ENV{'SERVER_PORT'} == 443) && ($hostname ne '')) { + unless (&Apache::lonnet::uses_sts()) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } + } if ($anchor ne '') { $backtourl .= '#'.&HTML::Entities::encode($anchor,'<>&"'); } @@ -6592,17 +6610,11 @@ sub editing_js { } my $fieldsets = "'ext','doc'"; - if ($posslti) { - $fieldsets .= ",'tool'"; - } unless ($main_container_page) { $fieldsets .=",'ims'"; } if ($supplementalflag) { $fieldsets = "'suppext','suppdoc'"; - if ($posslti) { - $fieldsets .= ",'supptool'"; - } } my $jsmakefunctions; @@ -6799,19 +6811,6 @@ function toggleUpload(caller) { } } document.getElementById('upload'+blocks[i]+'form').style.display=disp; - if ((caller == 'tool') || (caller == 'supptool')) { - if (disp == 'block') { - if (document.getElementById('LC_exttoolid')) { - var toolselector = document.getElementById('LC_exttoolid'); - var suppflag = 0; - if (caller == 'supptool') { - suppflag = 1; - } - currForm = document.getElementById('new'+caller); - updateExttool(toolselector,currForm,suppflag); - } - } - } } resize_scrollbox('contentscroll','1','1'); return; @@ -7789,7 +7788,7 @@ check on this Verify Content -=item devalidateversioncache() +=item devalidateversioncache() =item checkversions()