--- loncom/interface/londocs.pm 2006/07/20 01:18:26 1.238 +++ loncom/interface/londocs.pm 2012/07/13 13:36:24 1.491 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.238 2006/07/20 01:18:26 www Exp $ +# $Id: londocs.pm,v 1.491 2012/07/13 13:36:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,17 +33,20 @@ use Apache::Constants qw(:common :http); use Apache::imsexport; use Apache::lonnet; use Apache::loncommon; -use Apache::lonratedt; -use Apache::lonratsrv; +use Apache::lonhtmlcommon; +use LONCAPA::map(); +use Apache::lonratedt(); use Apache::lonxml; -use Apache::loncreatecourse; +use Apache::lonclonecourse; use Apache::lonnavmaps; +use Apache::lonnavdisplay(); +use Apache::lonuserstate(); use HTML::Entities; +use HTML::TokeParser; use GDBM_File; use Apache::lonlocal; use Cwd; -use lib '/home/httpd/lib/perl/'; -use LONCAPA; +use LONCAPA qw(:DEFAULT :match); my $iconpath; @@ -54,1221 +57,1614 @@ my %alreadyseen=(); my $hadchanges; -# Available help topics my %help=(); -# Mapread read maps into lonratedt::global arrays -# @order and @resources, determines status -# sets @order - pointer to resources in right order -# sets @resources - array with the resources with correct idx -# sub mapread { my ($coursenum,$coursedom,$map)=@_; return - &Apache::lonratedt::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'. - $map); + &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'. + $map); } sub storemap { my ($coursenum,$coursedom,$map)=@_; my ($outtext,$errtext)= - &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. - $map,1); + &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. + $map,1); if ($errtext) { return ($errtext,2); } - + $hadchanges=1; return ($errtext,0); } -# ----------------------------------------- Return hash with valid author names + sub authorhosts { my %outhash=(); my $home=0; my $other=0; - foreach (keys %env) { - if ($_=~/^user\.role\.(au|ca)\.(.+)$/) { + foreach my $key (keys(%env)) { + if ($key=~/^user\.role\.(au|ca)\.(.+)$/) { my $role=$1; my $realm=$2; - my ($start,$end)=split(/\./,$env{$_}); + my ($start,$end)=split(/\./,$env{$key}); if (($start) && ($start>time)) { next; } if (($end) && (time>$end)) { next; } - my $ca; my $cd; + my ($ca,$cd); if ($1 eq 'au') { $ca=$env{'user.name'}; $cd=$env{'user.domain'}; } else { - ($cd,$ca)=($realm=~/^\/(\w+)\/(\w+)$/); + ($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/); } my $allowed=0; my $myhome=&Apache::lonnet::homeserver($ca,$cd); my @ids=&Apache::lonnet::current_machine_ids(); - foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } } + foreach my $id (@ids) { + if ($id eq $myhome) { + $allowed=1; + last; + } + } if ($allowed) { $home++; - $outhash{'home_'.$ca.'@'.$cd}=1; + $outhash{'home_'.$ca.':'.$cd}=1; } else { - $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome; + $outhash{'otherhome_'.$ca.':'.$cd}=$myhome; $other++; } } } return ($home,$other,%outhash); } -# ------------------------------------------------------ Generate "dump" button -sub dumpbutton { - my ($home,$other,%outhash)=&authorhosts(); - my $type = &Apache::loncommon::course_type(); - if ($home+$other==0) { return ''; } - my $output='</td><td bgcolor="#DDDDCC">'; - if ($home) { - return '</td><td bgcolor="#DDDDCC">'. - '<input type="submit" name="dumpcourse" value="'. - &mt('Dump '.$type.' DOCS to Construction Space').'" />'. - &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs'); - } else { - return'</td><td bgcolor="#DDDDCC">'. - &mt('Dump '.$type. - ' DOCS to Construction Space: available on other servers'); - } -} sub clean { my ($title)=@_; $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs; - return $title; + return $title; } -# -------------------------------------------------------- Actually dump course + + sub dumpcourse { my ($r) = @_; - my $type = &Apache::loncommon::course_type(); - $r->print(&Apache::loncommon::start_page('Dump '.$type.' DOCS to Construction Space'). - '<form name="dumpdoc" method="post">'); + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Dump '.$crstype.' Content to Authoring Space')."\n". + &Apache::lonhtmlcommon::breadcrumbs('Dump '.$crstype.' Content to Authoring Space')."\n"); + $r->print(&startContentScreen('tools')); my ($home,$other,%outhash)=&authorhosts(); - unless ($home) { return ''; } + unless ($home) { + $r->print(&endContentScreen()); + return ''; + } my $origcrsid=$env{'request.course.id'}; my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid); if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) { # Do the dumping - unless ($outhash{'home_'.$env{'form.authorspace'}}) { return ''; } + unless ($outhash{'home_'.$env{'form.authorspace'}}) { + $r->print(&endContentScreen()); + return ''; + } my ($ca,$cd)=split(/\@/,$env{'form.authorspace'}); $r->print('<h3>'.&mt('Copying Files').'</h3>'); my $title=$env{'form.authorfolder'}; $title=&clean($title); my %replacehash=(); - foreach (keys %env) { - if ($_=~/^form\.namefor\_(.+)/) { - $replacehash{$1}=$env{$_}; + foreach my $key (keys(%env)) { + if ($key=~/^form\.namefor\_(.+)/) { + $replacehash{$1}=$env{$key}; } } my $crs='/uploaded/'.$env{'request.course.id'}.'/'; $crs=~s/\_/\//g; - foreach (keys %replacehash) { - my $newfilename=$title.'/'.$replacehash{$_}; + foreach my $item (keys(%replacehash)) { + my $newfilename=$title.'/'.$replacehash{$item}; $newfilename=~s/\.(\w+)$//; my $ext=$1; $newfilename=&clean($newfilename); $newfilename.='.'.$ext; my @dirs=split(/\//,$newfilename); - my $path='/home/'.$ca.'/public_html'; + my $path=$r->dir_config('lonDocRoot')."/priv/$cd/$ca"; my $makepath=$path; my $fail=0; for (my $i=0;$i<$#dirs;$i++) { $makepath.='/'.$dirs[$i]; - unless (-e $makepath) { - unless(mkdir($makepath,0777)) { $fail=1; } + unless (-e $makepath) { + unless(mkdir($makepath,0777)) { $fail=1; } } } - $r->print('<br /><tt>'.$_.'</tt> => <tt>'.$newfilename.'</tt>: '); + $r->print('<br /><tt>'.$item.'</tt> => <tt>'.$newfilename.'</tt>: '); if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) { - if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) { - print $fh &Apache::loncreatecourse::rewritefile( - &Apache::loncreatecourse::readfile($env{'request.course.id'},$_), + if ($item=~/\.(sequence|page|html|htm|xml|xhtml)$/) { + print $fh &Apache::lonclonecourse::rewritefile( + &Apache::lonclonecourse::readfile($env{'request.course.id'},$item), (%replacehash,$crs => '') ); } else { print $fh - &Apache::loncreatecourse::readfile($env{'request.course.id'},$_); + &Apache::lonclonecourse::readfile($env{'request.course.id'},$item); } $fh->close(); } else { $fail=1; } if ($fail) { - $r->print('<font color="red">fail</font>'); + $r->print('<span class="LC_error">'.&mt('fail').'</span>'); } else { - $r->print('<font color="green">ok</font>'); + $r->print('<span class="LC_success">'.&mt('ok').'</span>'); } } } else { + $r->print(&mt('Searching ...').'<br />'); + $r->rflush(); # Input form + $r->print('<form name="dumpdoc" action="" method="post">'."\n"); unless ($home==1) { - $r->print( - '<h3>'.&mt('Select the Construction Space').'</h3><select name="authorspace">'); + $r->print('<div class="LC_left_float">'. + '<fieldset><legend>'. + &mt('Select the Authoring Space'). + '</legend><select name="authorspace">'); } - foreach (sort keys %outhash) { - if ($_=~/^home_(.+)$/) { + foreach my $key (sort(keys(%outhash))) { + if ($key=~/^home_(.+)$/) { if ($home==1) { $r->print( '<input type="hidden" name="authorspace" value="'.$1.'" />'); } else { $r->print('<option value="'.$1.'">'.$1.' - '. - &Apache::loncommon::plainname(split(/\@/,$1)).'</option>'); + &Apache::loncommon::plainname(split(/\:/,$1)).'</option>'); } } } unless ($home==1) { - $r->print('</select>'); + $r->print('</select></fieldset></div>'."\n"); } my $title=$origcrsdata{'description'}; $title=~s/[\/\s]+/\_/gs; $title=&clean($title); - $r->print('<h3>'.&mt('Folder in Construction Space').'</h3><input type="text" size="50" name="authorfolder" value="'.$title.'" /><br />'); + $r->print('<div class="LC_left_float">'. + '<fieldset><legend>'.&mt('Folder in Authoring Space').'</legend>'. + '<input type="text" size="50" name="authorfolder" value="'. + $title.'" />'. + '</fieldset></div><br clear="all" />'."\n"); &tiehash(); - $r->print('<h3>'.&mt('Filenames in Construction Space').'</h3><table border="2"><tr><th>'.&mt('Internal Filename').'</th><th>'.&mt('Title').'</th><th>'.&mt('Save as ...').'</th></tr>'); - foreach (&Apache::loncreatecourse::crsdirlist($origcrsid,'userfiles')) { - $r->print('<tr><td>'.$_.'</td>'); - my ($ext)=($_=~/\.(\w+)$/); + $r->print('<h4>'.&mt('Filenames in Authoring Space').'</h4>' + .&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row() + .'<th>'.&mt('Internal Filename').'</th>' + .'<th>'.&mt('Title').'</th>' + .'<th>'.&mt('Save as ...').'</th>' + .&Apache::loncommon::end_data_table_header_row()); + foreach my $file (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) { + $r->print(&Apache::loncommon::start_data_table_row() + .'<td>'.$file.'</td>'); + my ($ext)=($file=~/\.(\w+)$/); my $title=$hash{'title_'.$hash{ - 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}}; - $title=~s/:/:/g; + 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$file}}; $r->print('<td>'.($title?$title:' ').'</td>'); if (!$title) { - $title=$_; + $title=$file; } else { $title=~s|/|_|g; } $title=~s/\.(\w+)$//; $title=&clean($title); $title.='.'.$ext; - $r->print("\n<td><input type='text' size='60' name='namefor_".$_."' value='".$title."' /></td></tr>\n"); + $r->print("\n<td><input type='text' size='60' name='namefor_".$file."' value='".$title."' /></td>" + .&Apache::loncommon::end_data_table_row()); } - $r->print("</table>\n"); + $r->print(&Apache::loncommon::end_data_table()); &untiehash(); $r->print( - '<p><input type="submit" name="dumpcourse" value="'.&mt('Dump [_1] DOCS',$type).'" /></p></form>'); + '<p><input type="submit" name="dumpcourse" value="'.&mt("Dump $crstype Content").'" /></p></form>'); } + $r->print(&endContentScreen()); } -# ------------------------------------------------------ Generate "export" button - -sub exportbutton { - my $type = &Apache::loncommon::course_type(); - return '</td><td bgcolor="#DDDDCC">'. - '<input type="submit" name="exportcourse" value="'. - &mt('Export '.$type.' to IMS').'" />'. - &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs'); -} +sub group_import { + my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_; -sub exportcourse { - my $r=shift; - my $type = &Apache::loncommon::course_type(); - my %discussiontime = &Apache::lonnet::dump('discussiontimes', - $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); - my $numdisc = keys %discussiontime; - my $navmap = Apache::lonnavmaps::navmap->new(); - my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef); - my $curRes; - my $outcome; + while (@files) { + my ($name, $url, $residx) = @{ shift(@files) }; + if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) + && ($caller eq 'londocs') + && (!&Apache::lonnet::stat_file($url))) { - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['finishexport']); - if ($env{'form.finishexport'}) { - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['archive','discussion']); - - my @exportitems = &Apache::loncommon::get_env_multiple('form.archive'); - my @discussions = &Apache::loncommon::get_env_multiple('form.discussion'); - if (@exportitems == 0 && @discussions == 0) { - $outcome = '<br />As you did not select any content items or discussions for export, an IMS package has not been created. Please <a href="javascript:history.go(-1)">go back</a> to select either content items or discussions for export'; - } else { - my $now = time; - my %symbs; - my $manifestok = 0; - my $imsresources; - my $tempexport; - my $copyresult; - my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport); - if ($manifestok) { - &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest); - close($ims_manifest); - -#Create zip file in prtspool - my $imszipfile = '/prtspool/'. - $env{'user.name'}.'_'.$env{'user.domain'}.'_'. - time.'_'.rand(1000000000).'.zip'; - my $cwd = &Cwd::getcwd(); - my $imszip = '/home/httpd/'.$imszipfile; - chdir $tempexport; - open(OUTPUT, "zip -r $imszip * 2> /dev/null |"); - close(OUTPUT); - chdir $cwd; - $outcome .= &mt('Download the zip file from <a href="[_1]">IMS '.lc($type).' archive</a><br />',$imszipfile,); - if ($copyresult) { - $outcome .= 'The following errors occurred during export - '.$copyresult; - } - } else { - $outcome = '<br />Unfortunately you will not be able to retrieve an IMS archive of this posts at this time, because there was a problem creating a manifest file.<br />'; + my $errtext = ''; + my $fatal = 0; + my $newmapstr = '<map>'."\n". + '<resource id="1" src="" type="start"></resource>'."\n". + '<link from="1" to="2" index="1"></link>'."\n". + '<resource id="2" src="" type="finish"></resource>'."\n". + '</map>'; + $env{'form.output'}=$newmapstr; + my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, + 'output',$1.$2); + if ($result != m|^/uploaded/|) { + $errtext.='Map not saved: A network error occurred when trying to save the new map. '; + $fatal = 2; } - } - $r->print(&Apache::loncommon::start_page('Export '.lc($type).' to IMS content package')); - $r->print($outcome); - $r->print(&Apache::loncommon::end_page()); - } else { - my $display; - $display = '<form name="exportdoc" method="post">'."\n"; - $display .= &mt('Choose which items you wish to export from your '.$type.'.<br /><br />'); - $display .= '<table border="0" cellspacing="0" cellpadding="3">'. - '<tr><td><fieldset><legend> <b>Content items</b></legend>'. - '<input type="button" value="check all" '. - 'onclick="javascript:checkAll(document.exportdoc.archive)" />'. - ' <input type="button" value="uncheck all"'. - ' onclick="javascript:uncheckAll(document.exportdoc.archive)" /></fieldset></td>'. - '<td> </td><td> </td>'. - '<td align="right"><fieldset><legend> <b>Discussion posts'. - '</b></legend><input type="button" value="check all"'. - ' onclick="javascript:checkAll(document.exportdoc.discussion)" />'. - ' <input type="button" value="uncheck all"'. - ' onclick="javascript:uncheckAll(document.exportdoc.discussion)" /></fieldset></td>'. - '</tr></table>'; - my $curRes; - my $depth = 0; - my $count = 0; - my $boards = 0; - my $startcount = 5; - my %parent = (); - my %children = (); - my $lastcontainer = $startcount; - my @bgcolors = ('#F6F6F6','#FFFFFF'); - $display .= '<table cellspacing="0"><tr>'. - '<td><b>Export content item?<br /></b></td><td> </td><td align="right">'."\n"; - if ($numdisc > 0) { - $display.='<b>Export discussion posts?</b>'."\n"; - } - $display.=' </td></tr>'; - while ($curRes = $it->next()) { - if (ref($curRes)) { - $count ++; - } - if ($curRes == $it->BEGIN_MAP()) { - $depth++; - $parent{$depth} = $lastcontainer; - } - if ($curRes == $it->END_MAP()) { - $depth--; - $lastcontainer = $parent{$depth}; - } - if (ref($curRes)) { - my $symb = $curRes->symb(); - my $ressymb = $symb; - if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { - unless ($ressymb =~ m|adm/wrapper/adm|) { - $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard'; - } - } - my $color = $count%2; - $display .='<tr bgcolor='.$bgcolors[$color].'><td>'."\n". - '<input type="checkbox" name="archive" value="'.$count.'" '; - if (($curRes->is_sequence()) || ($curRes->is_page())) { - my $checkitem = $count + $boards + $startcount; - $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"'; - } - $display .= ' />'."\n"; - for (my $i=0; $i<$depth; $i++) { - $display .= '<img src="/adm/lonIcons/whitespace1.gif" width="25" height="1" alt="" border="0" /><img src="/adm/lonIcons/whitespace1.gif" width="25" height="1" alt="" border="0" />'."\n"; - } - if ($curRes->is_sequence()) { - $display .= '<img src="/adm/lonIcons/navmap.folder.open.gif"> '."\n"; - $lastcontainer = $count + $startcount + $boards; - } elsif ($curRes->is_page()) { - $display .= '<img src="/adm/lonIcons/navmap.page.open.gif"> '."\n"; - $lastcontainer = $count + $startcount + $boards; - } - my $currelem = $count+$boards+$startcount; - $children{$parent{$depth}} .= $currelem.':'; - $display .= ' '.$curRes->title().'</td>'; - if ($discussiontime{$ressymb} > 0) { - $boards ++; - $currelem = $count+$boards+$startcount; - $display .= '<td> </td><td align="right"><input type="checkbox" name="discussion" value="'.$count.'" /> </td>'."\n"; - } else { - $display .= '<td colspan="2"> </td>'."\n"; - } + if ($fatal) { + return ($errtext,$fatal); } } - my $scripttag = qq| -<script> + if ($url) { + if (!$residx + || defined($LONCAPA::map::zombies[$residx])) { + $residx = &LONCAPA::map::getresidx($url,$residx); + push(@LONCAPA::map::order, $residx); + } + my $ext = 'false'; + if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } + $url = &LONCAPA::map::qtunescape($url); + $name = &LONCAPA::map::qtunescape($name); + $LONCAPA::map::resources[$residx] = + join(':', ($name, $url, $ext, 'normal', 'res')); + } + } + return &storemap($coursenum, $coursedom, $folder.'.'.$container); +} -function checkAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = true ; - } +sub breadcrumbs { + my ($allowed,$crstype)=@_; + &Apache::lonhtmlcommon::clear_breadcrumbs(); + my (@folders); + if ($env{'form.pagepath'}) { + @folders = split('&',$env{'form.pagepath'}); } else { - field.checked = true + @folders=split('&',$env{'form.folderpath'}); } -} - -function uncheckAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = false ; + my $folderpath; + my $cpinfo=''; + my $plain=''; + my $randompick=-1; + my $isencrypted=0; + my $ishidden=0; + my $is_random_order=0; + while (@folders) { + my $folder=shift(@folders); + my $foldername=shift(@folders); + if ($folderpath) {$folderpath.='&';} + $folderpath.=$folder.'&'.$foldername; + my $url; + if ($allowed) { + $url = '/adm/coursedocs?folderpath='; + } else { + $url = '/adm/supplemental?folderpath='; + } + $url .= &escape($folderpath); + my $name=&unescape($foldername); +# randompick number, hidden, encrypted, random order, is appended with ":"s to the foldername + $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)$//; + if ($1 ne '') { + $randompick=$1; + } else { + $randompick=-1; + } + if ($2) { $ishidden=1; } + if ($3) { $isencrypted=1; } + if ($4 ne '') { $is_random_order = 1; } + if ($folder eq 'supplemental') { + $name = &mt('Supplemental '.$crstype.' Content'); + } + &Apache::lonhtmlcommon::add_breadcrumb( + {'href'=>$url.$cpinfo, + 'title'=>$name, + 'text'=>$name, + 'no_mt'=>1, + }); + $plain.=$name.' > '; + } + $plain=~s/\>\;\s*$//; + return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp', + undef, undef, 1 ),$randompick,$ishidden, + $isencrypted,$plain,$is_random_order); +} + +sub log_docs { + return &Apache::lonnet::instructor_log('docslog',@_); +} + +{ + my @oldresources=(); + my @oldorder=(); + my $parmidx; + my %parmaction=(); + my %parmvalue=(); + my $changedflag; + + sub snapshotbefore { + @oldresources=@LONCAPA::map::resources; + @oldorder=@LONCAPA::map::order; + $parmidx=undef; + %parmaction=(); + %parmvalue=(); + $changedflag=0; + } + + sub remember_parms { + my ($idx,$parameter,$action,$value)=@_; + $parmidx=$idx; + $parmaction{$parameter}=$action; + $parmvalue{$parameter}=$value; + $changedflag=1; + } + + sub log_differences { + my ($plain)=@_; + my %storehash=('folder' => $plain, + 'currentfolder' => $env{'form.folder'}); + if ($parmidx) { + $storehash{'parameter_res'}=$oldresources[$parmidx]; + foreach my $parm (keys(%parmaction)) { + $storehash{'parameter_action_'.$parm}=$parmaction{$parm}; + $storehash{'parameter_value_'.$parm}=$parmvalue{$parm}; + } } + my $maxidx=$#oldresources; + if ($#LONCAPA::map::resources>$#oldresources) { + $maxidx=$#LONCAPA::map::resources; + } + for (my $idx=0; $idx<=$maxidx; $idx++) { + if ($LONCAPA::map::resources[$idx] ne $oldresources[$idx]) { + $storehash{'before_resources_'.$idx}=$oldresources[$idx]; + $storehash{'after_resources_'.$idx}=$LONCAPA::map::resources[$idx]; + $changedflag=1; + } + if ($LONCAPA::map::order[$idx] ne $oldorder[$idx]) { + $storehash{'before_order_res_'.$idx}=$oldresources[$oldorder[$idx]]; + $storehash{'after_order_res_'.$idx}=$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]; + $changedflag=1; + } + } + $storehash{'maxidx'}=$maxidx; + if ($changedflag) { &log_docs(\%storehash); } + } +} + +sub docs_change_log { + my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_; + my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + my $js = '<script type="text/javascript">'."\n". + '// <![CDATA['."\n". + &Apache::loncommon::display_filter_js('docslog')."\n". + &editing_js($env{'user.domain'},$env{'user.name'},$supplementalflag)."\n". + &history_tab_js()."\n". + &Apache::lonratedt::editscript('simple')."\n". + '// ]]>'."\n". + '</script>'."\n"; + $r->print(&Apache::loncommon::start_page('Content Change Log',$js)); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Change Log')); + $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs'))); + my %orderhash; + my $container='sequence'; + my $pathitem; + if ($env{'form.pagepath'}) { + $container='page'; + $pathitem = '<input type="hidden" name="pagepath" value="'. + &HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />'; } else { - field.checked = false ; + my $folderpath=$env{'form.folderpath'}; + if ($folderpath eq '') { + $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents')); + } + $pathitem = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />'; + } + my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; + my $jumpto = $readfile; + $jumpto =~ s{^/}{}; + my $tid = 1; + if ($supplementalflag) { + $tid = 2; + } + my ($breadcrumbtrail) = &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail. + &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto, + $readfile)); + my %docslog=&Apache::lonnet::dump('nohist_docslog', + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + + if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); } + + my %saveable_parameters = ('show' => 'scalar',); + &Apache::loncommon::store_course_settings('docs_log', + \%saveable_parameters); + &Apache::loncommon::restore_course_settings('docs_log', + \%saveable_parameters); + if (!$env{'form.show'}) { $env{'form.show'}=10; } +# FIXME: internationalization seems wrong here + my %lt=('hiddenresource' => 'Resources hidden', + 'encrypturl' => 'URL hidden', + 'randompick' => 'Randomly pick', + 'randomorder' => 'Randomly ordered', + 'set' => 'set to', + 'del' => 'deleted'); + my $filter = &Apache::loncommon::display_filter('docslog')."\n". + $pathitem."\n". + '<input type="hidden" name="folder" value="'.$env{'form.folder'}.'" />'. + (' 'x2).'<input type="submit" value="'.&mt('Display').'" />'; + $r->print('<div class="LC_left_float">'. + '<fieldset><legend>'.&mt('Display of Content Changes').'</legend>'."\n". + &makedocslogform($filter,1). + '</fieldset></div><br clear="all" />'); + $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Folder').'</th><th>'.&mt('Before').'</th><th>'. + &mt('After').'</th>'. + &Apache::loncommon::end_data_table_header_row()); + my $shown=0; + foreach my $id (sort { $docslog{$b}{'exe_time'}<=>$docslog{$a}{'exe_time'} } (keys(%docslog))) { + if ($env{'form.displayfilter'} eq 'currentfolder') { + if ($docslog{$id}{'logentry'}{'currentfolder'} ne $folder) { next; } + } + my @changes=keys(%{$docslog{$id}{'logentry'}}); + if ($env{'form.displayfilter'} eq 'containing') { + my $wholeentry=$docslog{$id}{'exe_uname'}.':'.$docslog{$id}{'exe_udom'}.':'. + &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},$docslog{$id}{'exe_udom'}); + foreach my $key (@changes) { + $wholeentry.=':'.$docslog{$id}{'logentry'}{$key}; + } + if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; } + } + my $count = 0; + my $time = + &Apache::lonlocal::locallocaltime($docslog{$id}{'exe_time'}); + my $plainname = + &Apache::loncommon::plainname($docslog{$id}{'exe_uname'}, + $docslog{$id}{'exe_udom'}); + my $about_me_link = + &Apache::loncommon::aboutmewrapper($plainname, + $docslog{$id}{'exe_uname'}, + $docslog{$id}{'exe_udom'}); + my $send_msg_link=''; + if ((($docslog{$id}{'exe_uname'} ne $env{'user.name'}) + || ($docslog{$id}{'exe_udom'} ne $env{'user.domain'}))) { + $send_msg_link ='<br />'. + &Apache::loncommon::messagewrapper(&mt('Send message'), + $docslog{$id}{'exe_uname'}, + $docslog{$id}{'exe_udom'}); + } + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print('<td>'.$time.'</td> + <td>'.$about_me_link. + '<br /><tt>'.$docslog{$id}{'exe_uname'}. + ':'.$docslog{$id}{'exe_udom'}.'</tt>'. + $send_msg_link.'</td><td>'. + $docslog{$id}{'logentry'}{'folder'}.'</td><td>'); + my $is_supp = 0; + if ($docslog{$id}{'logentry'}{'currentfolder'} =~ /^supplemental/) { + $is_supp = 1; + } +# Before + for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) { + my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0]; + my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0]; + if ($oldname ne $newname) { + my $shown = &LONCAPA::map::qtescape($oldname); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title($shown); + } + $r->print($shown); + } + } + $r->print('<ul>'); + for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) { + if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) { + my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title($shown); + } + $r->print('<li>'.$shown.'</li>'); + } + } + $r->print('</ul>'); +# After + $r->print('</td><td>'); + + for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) { + my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0]; + my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0]; + if ($oldname ne '' && $oldname ne $newname) { + my $shown = &LONCAPA::map::qtescape($newname); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($newname)); + } + $r->print($shown); + } + } + $r->print('<ul>'); + for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) { + if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) { + my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]); + if ($is_supp) { + $shown = &Apache::loncommon::parse_supplemental_title($shown); + } + $r->print('<li>'.$shown.'</li>'); + } + } + $r->print('</ul>'); + if ($docslog{$id}{'logentry'}{'parameter_res'}) { + $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':<ul>'); + foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder') { + if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) { +# FIXME: internationalization seems wrong here + $r->print('<li>'. + &mt($lt{$parameter}.' '.$lt{$docslog{$id}{'logentry'}{'parameter_action_'.$parameter}}.' [_1]', + $docslog{$id}{'logentry'}{'parameter_value_'.$parameter}) + .'</li>'); + } + } + $r->print('</ul>'); + } +# End + $r->print('</td>'.&Apache::loncommon::end_data_table_row()); + $shown++; + if (!($env{'form.show'} eq &mt('all') + || $shown<=$env{'form.show'})) { last; } } + $r->print(&Apache::loncommon::end_data_table()."\n". + &makesimpleeditform($pathitem)."\n". + '</div></div>'); + $r->print(&endContentScreen()); } -function propagateCheck(item) { - if (document.exportdoc.elements[item].checked == true) { - containerCheck(item) +sub update_paste_buffer { + my ($coursenum,$coursedom) = @_; + + return if (!defined($env{'form.markcopy'})); + return if (!defined($env{'form.copyfolder'})); + return if ($env{'form.markcopy'} < 0); + + my ($errtext,$fatal) = &mapread($coursenum,$coursedom, + $env{'form.copyfolder'}); + + return if ($fatal); + +# Mark for copying + my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]); + if (&is_supplemental_title($title)) { + &Apache::lonnet::appenv({'docs.markedcopy_supplemental' => $title}); + ($title) = &Apache::loncommon::parse_supplemental_title($title); + } elsif ($env{'docs.markedcopy_supplemental'}) { + &Apache::lonnet::delenv('docs.markedcopy_supplemental'); } -} + $url=~s{http(:|:)//https(:|:)//}{https$2//}; + + &Apache::lonnet::appenv({'docs.markedcopy_title' => $title, + 'docs.markedcopy_url' => $url}); + delete($env{'form.markcopy'}); +} -function containerCheck(item) { - document.exportdoc.elements[item].checked = true - var numitems = $count + $boards + $startcount - var parents = new Array(numitems) - for (var i=$startcount; i<numitems; i++) { - parents[i] = new Array +sub print_paste_buffer { + my ($r,$container,$folder) = @_; + return if (!defined($env{'docs.markedcopy_url'})); + + my $is_external; + my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1]; + if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) { + $is_external = 1; } - |; - foreach my $container (sort { $a <=> $b } keys %children) { - my @contents = split/:/,$children{$container}; - for (my $i=0; $i<@contents; $i ++) { - $scripttag .= ' parents['.$container.']['.$i.'] = '.$contents[$i]."\n"; - } - } + my $canpaste; + if ($folder =~ /^supplemental/) { + $canpaste = &supp_pasteable($env{'docs.markedcopy_url'}); + } else { + $canpaste = 1; + } - $scripttag .= qq| - if (parents[item].length > 0) { - for (var j=0; j<parents[item].length; j++) { - containerCheck(parents[item][j]) + my $pasteinfo; + if ($canpaste) { + $pasteinfo = '<form name="pasteform" action="/adm/coursedocs" method="post">' + .'<input type="submit" name="pastemarked" value="'.&mt('Paste').'" /> '; + } else { + $pasteinfo = &mt('Paste buffer contains:').' '; + } + + $r->print('<fieldset>' + .'<legend>'.&mt('Clipboard').'</legend>' + .$pasteinfo + ); + + my $type; + if ($is_external) { + $type = &mt('External Resource'); + $r->print($type.': '. + &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('. + &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')'); + } else { + my $icon = &Apache::loncommon::icon($extension); + if ($extension eq 'sequence' && + $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) { + $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL')); + $icon .= '/navmap.folder.closed.gif'; + } + $icon = '<img src="'.$icon.'" alt="" class="LC_icon" />'; + $r->print($icon.$type.': '. &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}))); + } + if ($canpaste) { + if ($container eq 'page') { + $r->print(' + <input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" /> + <input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" /> +'); + } else { + $r->print(' + <input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" /> +'); } - } + $r->print('</form>'); + } else { + $r->print('<br /><p class="LC_info">'.&mt('Paste into Supplemental Content unavailable for this type of content.').'</p>'); + } + $r->print('</fieldset>'); } -</script> - |; - $r->print(&Apache::loncommon::start_page('Export '.lc($type).' to IMS content package', - $scripttag)); - $r->print($display.'</table>'. - '<p><input type="hidden" name="finishexport" value="1">'. - '<input type="submit" name="exportcourse" value="'. - &mt('Export '.$type.' DOCS').'" /></p></form>'. - &Apache::loncommon::end_page()); +sub supp_pasteable { + my ($url) = @_; + if (($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//}) || + (($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})) { + return 1; } + return; } -sub create_ims_store { - my ($now,$manifestok,$outcome,$tempexport) = @_; - $$tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports'; - my $ims_manifest; - if (!-e $$tempexport) { - mkdir($$tempexport,0700); - } - $$tempexport .= '/'.$now; - if (!-e $$tempexport) { - mkdir($$tempexport,0700); - } - $$tempexport .= '/'.$env{'user.domain'}.'_'.$env{'user.name'}; - if (!-e $$tempexport) { - mkdir($$tempexport,0700); - } - if (!-e "$$tempexport/resources") { - mkdir("$$tempexport/resources",0700); - } -# open manifest file - my $manifest = '/imsmanifest.xml'; - my $manifestfilename = $$tempexport.$manifest; - if ($ims_manifest = Apache::File->new('>'.$manifestfilename)) { - $$manifestok=1; - print $ims_manifest -'<?xml version="1.0" encoding="UTF-8"?>'."\n". -'<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"'. -' xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2"'. -' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'. -' identifier="MANIFEST-'.$env{'request.course.id'}.'-'.$now.'"'. -' xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1imscp_v1p1.xsd'. -' http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">'."\n". -' <metadata> - <schema></schema> - <imsmd:lom> - <imsmd:general> - <imsmd:identifier>'.$env{'request.course.id'}.'</imsmd:identifier> - <imsmd:title> - <imsmd:langstring xml:lang="en">'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</imsmd:langstring> - </imsmd:title> - </imsmd:general> - </imsmd:lom> - </metadata>'."\n". -' <organizations default="ORG-'.$env{'request.course.id'}.'-'.$now.'">'."\n". -' <organization identifier="ORG-'.$env{'request.course.id'}.'-'.$now.'"'. -' structure="hierarchical">'."\n". -' <title>'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</title>' - } else { - $$outcome .= 'An error occurred opening the IMS manifest file.<br />' -; +sub do_paste_from_buffer { + my ($coursenum,$coursedom,$folder,$errors) = @_; + + if (!$env{'form.pastemarked'}) { + return; } - return $ims_manifest; -} -sub build_package { - my ($now,$navmap,$exportitems,$discussions,$outcome,$tempexport,$copyresult,$ims_manifest) = @_; -# first iterator to look for dependencies - my $it = $navmap->getIterator(undef,undef,undef,1,undef,undef); - my $curRes; - my $count = 0; - my $depth = 0; - my $lastcontainer = 0; - my %parent = (); - my @dependencies = (); - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - while ($curRes = $it->next()) { - if (ref($curRes)) { - $count ++; +# Preparing to paste resource at end of list + my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'}); + my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'}); + + my ($is_map,$srcdom,$srcnum,$prefixchg,%before,%after,%mapchanges); + if ($url=~/\.(page|sequence)$/) { + $is_map = 1; + } + if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/([^/]+)}) { + $srcdom = $1; + $srcnum = $2; + my $oldprefix = $3; + if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { + unless ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) { + return &mt('Paste failed: Item is from a different course which you do not have rights to edit.'); + } } - if ($curRes == $it->BEGIN_MAP()) { - $depth++; - $parent{$depth} = $lastcontainer; + if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) { + $prefixchg = 1; + %before = ( map => 'default', + doc => 'docs'); + %after = ( map => 'supplemental', + doc => 'supplemental' ); + } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) { + $prefixchg = 1; + %before = ( map => 'supplemental', + doc => 'supplemental'); + %after = ( map => 'default', + doc => 'docs'); } - if ($curRes == $it->END_MAP()) { - $depth--; - $lastcontainer = $parent{$depth}; + } + +# Supplemental content may only include certain types of content + if ($folder =~ /^supplemental/) { + unless (&supp_pasteable($env{'docs.markedcopy_url'})) { + return &mt('Paste failed: content type is not supported within Supplemental Content'); } - if (ref($curRes)) { - if ($curRes->is_sequence() || $curRes->is_page()) { - $lastcontainer = $count; + } + +# Maps need to be copied first + my ($oldurl,%removefrommap,%addedmaps,%rewrites,%retitles,%copies,%dbcopies,%zombies, + %params,%docmoves,%mapmoves); + $oldurl = $url; + if ($is_map) { +# If pasting a map, check if map contains other maps + my %allmaps; + &contained_map_check($url,$folder,\%removefrommap,\%addedmaps); + if ($folder =~ /^default/) { + if (keys(%addedmaps) > 0) { + &reinit_role($coursedom,$coursenum,$env{"course.$env{'request.course.id'}.home"}); } - if (grep/^$count$/,@$exportitems) { - &get_dependencies($exportitems,\%parent,$depth,\@dependencies); + my $navmap = Apache::lonnavmaps::navmap->new(); + if (defined($navmap)) { + foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) { + $allmaps{$res->src()} = 1; + } } } - } -# second iterator to build manifest and store resources - $it = $navmap->getIterator(undef,undef,undef,1,undef,undef); - $depth = 0; - my $prevdepth; - $count = 0; - my $imsresources; - my $pkgdepth; - while ($curRes = $it->next()) { - if ($curRes == $it->BEGIN_MAP()) { - $prevdepth = $depth; - $depth++; + if ($url=~ m{^/uploaded/}) { + $title=&mt('Copy of').' '.$title; } - if ($curRes == $it->END_MAP()) { - $prevdepth = $depth; - $depth--; + my $now = time; + my $suffix=$$.int(rand(100)).$now; + my ($oldid,$ext) = ($url=~/^(.+)\.(\w+)$/); + if ($oldid =~ m{^(/uploaded/$match_domain/$match_courseid/)(\D+)(\d+)$}) { + my $path = $1; + my $prefix = $2; + my $ancestor = $3; + if (length($ancestor) > 10) { + $ancestor = substr($ancestor,-10,10); + } + my ($newurl,$newid); + if ($prefixchg) { + if ($folder =~ /^supplemental/) { + $prefix =~ s/^default/supplemental/; + } else { + $prefix =~ s/^supplemental/default/; + } + } + if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) { + $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext; + } else { + $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$now.'.'.$ext; + } + my $counter = 0; + my $is_unique = &uniqueness_check($newurl); + if ($folder =~ /^default/) { + if ($allmaps{$newurl}) { + $is_unique = 0; + } + } + while (!$is_unique && $allmaps{$newurl} && $counter < 100) { + $counter ++; + $suffix ++; + if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) { + $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext; + } else { + $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$ancestor.$suffix.'.'.$ext; + } + $is_unique = &uniqueness_check($newurl); + } + if ($is_unique) { + if ($newurl ne $oldurl) { + $mapchanges{$oldurl} = 1; + } + if (($srcdom ne $coursedom) || ($srcnum ne $coursenum) || ($prefixchg)) { + &url_paste_fixups($url,$prefixchg,$coursedom,$coursenum,\%allmaps, + \%rewrites,\%retitles,\%copies,\%dbcopies,\%zombies, + \%params,\%mapmoves,\%mapchanges); + } + } else { + if ($url=~/\.page$/) { + return &mt('Paste failed: an error occurred creating a unique URL for the composite page'); + } else { + return &mt('Paste failed: an error occurred creating a unique URL for the folder'); + } + } + my $storefn=$newurl; + $storefn=~s{^/\w+/$match_domain/$match_username/}{}; + my $paste_map_result = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn, + &Apache::lonnet::getfile($url)); + if ($paste_map_result eq '/adm/notfound.html') { + if ($url=~/\.page$/) { + return &mt('Paste failed: an error occurred saving the composite page.'); + } else { + return &mt('Paste failed: an error occurred saving the folder.'); + } + } + $url = $newurl; + } elsif ($url=~m {^/res/}) { +# published maps can only exists once, so remove it from paste buffer when done + &Apache::lonnet::delenv('docs.markedcopy'); + if ($folder =~ /^default/) { + if ($allmaps{$url}) { + return &mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.'); + } + } } + } + if ($url=~ m{/smppg$}) { + my $db_name = &Apache::lonsimplepage::get_db_name($url); + if ($db_name =~ /^smppage_/) { + #simple pages, need to copy the db contents to a new one. + my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); + my $now = time(); + $db_name =~ s{_\d*$ }{_$now}x; + my $dbresult=&Apache::lonnet::put($db_name,\%contents, + $coursedom,$coursenum); + if ($dbresult eq 'ok') { + $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + $title=&mt('Copy of').' '.$title; + } else { + return &mt('Paste failed: An error occurred when copying the simple page.'); + } + } + } + $title = &LONCAPA::map::qtunescape($title); + my $ext='false'; + if ($url=~m{^http(|s)://}) { $ext='true'; } + $url = &LONCAPA::map::qtunescape($url); +# Now insert the URL at the bottom + my $newidx = &LONCAPA::map::getresidx($url); - if (ref($curRes)) { - $count ++; - if ((grep/^$count$/,@$exportitems) || (grep/^$count$/,@dependencies)) { - my $symb = $curRes->symb(); - my $isvisible = 'true'; - my $resourceref; - if ($curRes->randomout()) { - $isvisible = 'false'; - } - unless ($curRes->is_sequence()) { - $resourceref = 'identifierref="RES-'.$env{'request.course.id'}.'-'.$count.'"'; - } - my $step = $prevdepth - $depth; - if (($step >= 0) && ($count > 1)) { - while ($step >= 0) { - print $ims_manifest "\n".' </item>'."\n"; - $step --; - } +# For uploaded files (excluding pages/sequences) path in copied file is changed +# if paste is from Main to Supplemental (or vice versa), or if pasting between +# courses. + + unless ($is_map) { + if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) { + my $relpath = $1; + if ($relpath ne '') { + my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$}); + my ($newloc,$newsubdir) = ($folder =~ /^(default|supplemental)_?(\d*)/); + my $newprefix = $newloc; + if ($newloc eq 'default') { + $newprefix = 'docs'; } - $prevdepth = $depth; - - my $itementry = - '<item identifier="ITEM-'.$env{'request.course.id'}.'-'.$count. - '" isvisible="'.$isvisible.'" '.$resourceref.'>'. - '<title>'.$curRes->title().'</title>'; - print $ims_manifest "\n".$itementry; - - unless ($curRes->is_sequence()) { - my $content_file; - my @hrefs = (); - &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport); - if ($content_file) { - $imsresources .= "\n". - ' <resource identifier="RES-'.$env{'request.course.id'}.'-'.$count. - '" type="webcontent" href="'.$content_file.'">'."\n". - ' <file href="'.$content_file.'" />'."\n"; - foreach (@hrefs) { - $imsresources .= - ' <file href="'.$_.'" />'."\n"; - } - if (grep/^$count$/,@$discussions) { - my $ressymb = $symb; - my $mode; - if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { - unless ($ressymb =~ m|adm/wrapper/adm|) { - $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard'; - } - $mode = 'board'; - } - my %extras = ( - caller => 'imsexport', - tempexport => $tempexport.'/resources', - count => $count - ); - my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras); - } - $imsresources .= ' </resource>'."\n"; + if ($newsubdir eq '') { + $newsubdir = 'default'; + } + if (($prefixchg) || ($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { + my $newpath = "$newprefix/$newsubdir/$newidx/$rem"; + $url = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, + &Apache::lonnet::getfile($oldurl)); + if ($url eq '/adm/notfound.html') { + return &mt('Paste failed: an error occurred saving the file.'); + } else { + my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$}); + $newsubpath =~ s{/+$}{/}; + $docmoves{$oldurl} = $newsubpath; } } - $pkgdepth = $depth; } } } - while ($pkgdepth > 0) { - print $ims_manifest " </item>\n"; - $pkgdepth --; - } - my $resource_text = qq| - </organization> - </organizations> - <resources> - $imsresources - </resources> -</manifest> - |; - print $ims_manifest $resource_text; -} - -sub get_dependencies { - my ($exportitems,$parent,$depth,$dependencies) = @_; - if ($depth > 1) { - if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) { - push @$dependencies, $$parent{$depth}; - if ($depth > 2) { - &get_dependencies($exportitems,$parent,$depth-1,$dependencies); + my $result = + &apply_fixups($is_map,$prefixchg,$coursedom,$coursenum,$oldurl,$url, + \%removefrommap,\%rewrites,\%retitles,\%copies,\%dbcopies, + \%zombies,\%params,\%docmoves,\%mapmoves,$errors,\%before,\%after); + if ($result eq 'ok') { + if ($env{'docs.markedcopy_supplemental'}) { + if ($folder =~ /^supplemental/) { + $title = $env{'docs.markedcopy_supplemental'}; + } else { + (undef,undef,$title) = + &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental'}); + } + } else { + if ($folder=~/^supplemental/) { + $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'. + $env{'user.domain'}.'___&&&___'.$title; } } + $LONCAPA::map::resources[$newidx]= $title.':'.$url.':'.$ext.':normal:res'; + push(@LONCAPA::map::order, $newidx); } + return $result; } -sub process_content { - my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport) = @_; - my $content_type; - my $message; - my @uploads = (); - if ($curRes->is_sequence()) { - $content_type = 'sequence'; - } elsif ($curRes->is_page()) { - $content_type = 'page'; # need to handle individual items in pages. - } elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) { - $content_type = 'syllabus'; - my $contents = &Apache::imsexport::templatedpage($content_type); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-\.sequence___\d+___ext-) { - $content_type = 'external'; - my $title = $curRes->title; - my $contents = &Apache::imsexport::external($symb,$title); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-adm/navmaps$-) { - $content_type = 'navmap'; - } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) { - $content_type = 'simplepage'; - my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) { - $content_type = 'simpleproblem'; - my $contents = &Apache::imsexport::simpleproblem($symb); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-lib/templates/examupload\.problem$-) { - $content_type = 'examupload'; - } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) { - $content_type = 'bulletinboard'; - my $contents = &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) { - $content_type = 'aboutme'; - my $contents = &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2); - if ($contents) { - $$content_file = &store_template($contents,$tempexport,$count,$content_type); - } - } elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) { - $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded'); - } elsif ($symb =~ m-\.(sequence|page)___\d+___([^/]+)/([^/]+)-) { - my $canedit = 0; - if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'}) { - $canedit= 1; - } -# only include problem code where current user is author - if ($canedit) { - $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource'); - } else { - $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit'); - } - } elsif ($symb =~ m-uploaded/$cdom/$cnum-) { - $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded'); - } - if (@uploads > 0) { - foreach my $item (@uploads) { - my $uploadmsg = ''; - &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'templateupload'); - if ($uploadmsg) { - $$copyresult .= $uploadmsg."\n"; +sub dbcopy { + my ($url,$coursedom,$coursenum) = @_; + if ($url=~ m{/smppg$}) { + my $db_name = &Apache::lonsimplepage::get_db_name($url); + if ($db_name =~ /^smppage_/) { + #simple pages, need to copy the db contents to a new one. + my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); + my $now = time(); + $db_name =~ s{_\d*$ }{_$now}x; + my $result=&Apache::lonnet::put($db_name,\%contents, + $coursedom,$coursenum); + $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + } + } + return $url; +} + +sub uniqueness_check { + my ($newurl) = @_; + my $unique = 1; + foreach my $res (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); + $url=&LONCAPA::map::qtescape($url); + if ($newurl eq $url) { + $unique = 0; + last; + } + } + return $unique; +} + +sub contained_map_check { + my ($url,$folder,$removefrommap,$addedmaps) = @_; + my $content = &Apache::lonnet::getfile($url); + unless ($content eq '-1') { + my $parser = HTML::TokeParser->new(\$content); + $parser->attr_encoded(1); + while (my $token = $parser->get_token) { + next if ($token->[0] ne 'S'); + if ($token->[1] eq 'resource') { + next if ($token->[2]->{'type'} eq 'zombie'); + my $ressrc = $token->[2]->{'src'}; + if ($folder =~ /^supplemental/) { + unless (&supp_pasteable($ressrc)) { + $removefrommap->{$url}{$token->[2]->{'id'}}; + next; + } + } + if ($ressrc =~ /\.(sequence|page)$/) { + if (ref($addedmaps->{$ressrc}) eq 'ARRAY') { + push(@{$addedmaps->{$ressrc}},$url); + } else { + $addedmaps->{$ressrc} = [$url]; + } + &contained_map_check($ressrc,$folder,$removefrommap,$addedmaps); + } + } elsif ($token->[1] !~ /^resource|map|link$/) { + if ($folder =~ /^supplemental/) { + $removefrommap->{$url}{$token->[1]}; + } } } } - if ($message) { - $$copyresult .= $message."\n"; - } + return; } -sub replicate_content { - my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_; - my ($map,$ind,$url); - if ($caller eq 'templateupload') { - $url = $symb; - $url =~ s#//#/#g; - } else { - ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); +sub reinit_role { + my ($cdom,$cnum,$chome) = @_; + my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); + unless ($ferr) { + &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,$cdom.'_'.$cnum); } - my $content; - my $filename; - my $repstatus; - my $content_name; - if ($url =~ m-/([^/]+)$-) { - $filename = $1; - if (!-e $tempexport.'/resources') { - mkdir($tempexport.'/resources',0700); - } - if (!-e $tempexport.'/resources/'.$count) { - mkdir($tempexport.'/resources/'.$count,0700); - } - my $destination = $tempexport.'/resources/'.$count.'/'.$filename; - my $copiedfile; - if ($copiedfile = Apache::File->new('>'.$destination)) { - my $content; - if ($caller eq 'resource') { - my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res'; - my $filepath = &Apache::lonnet::filelocation($respath,$url); - $content = &Apache::lonnet::getfile($filepath); - if ($content eq -1) { - $$message = 'Could not copy file '.$filename; - } else { - &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource'); - $repstatus = 'ok'; + return; +} + +sub url_paste_fixups { + my ($oldurl,$prefixchg,$cdom,$cnum,$allmaps,$rewrites,$retitles,$copies, + $dbcopies,$zombies,$params,$mapmoves,$mapchanges) = @_; + my $checktitle; + if (($prefixchg) && + ($oldurl =~ m{^/uploaded/($match_domain)/($match_courseid)/supplemental})) { + $checktitle = 1; + } + my $file = &Apache::lonnet::getfile($oldurl); + return if ($file eq '-1'); + my $parser = HTML::TokeParser->new(\$file); + $parser->attr_encoded(1); + my $changed = 0; + while (my $token = $parser->get_token) { + next if ($token->[0] ne 'S'); + if ($token->[1] eq 'resource') { + my $ressrc = $token->[2]->{'src'}; + next if ($ressrc eq ''); + my $id = $token->[2]->{'id'}; + if ($checktitle) { + my $title = $token->[2]->{'title'}; + if ($title =~ m{\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { + $retitles->{$oldurl}{$ressrc} = $id; + } - } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') { - my $rtncode; - $repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode); - if ($repstatus eq 'ok') { - if ($url =~ /\.html?$/i) { - &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded'); + } + next if ($token->[2]->{'type'} eq 'external'); + if ($token->[2]->{'type'} eq 'zombie') { + $zombies->{$oldurl}{$ressrc} = $id; + $changed = 1; + } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { + my $srccdom = $1; + my $srccnum = $2; + my $rem = $3; + if (($srccdom ne $cdom) || ($srccnum ne $cnum) || ($prefixchg) || + ($mapchanges->{$oldurl})) { + if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) { + $rewrites->{$oldurl}{$ressrc} = $id; + $mapchanges->{$ressrc} = 1; + unless (&url_paste_fixups($ressrc,$prefixchg,$cdom,$cnum,$allmaps, + $rewrites,$retitles,$copies,$dbcopies,$zombies, + $params,$mapmoves,$mapchanges)) { + $mapmoves->{$ressrc} = 1; + } + $changed = 1; + } else { + $rewrites->{$oldurl}{$ressrc} = $id; + $copies->{$oldurl}{$ressrc} = $id; + $changed = 1; } - } else { - $$message = 'Could not render '.$url.' server message - '.$rtncode."<br />\n"; } - } elsif ($caller eq 'noedit') { -# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this. - $repstatus = 'ok'; - $content = 'Not the owner of this resource'; + } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) { + my $srccdom = $1; + my $srccnum = $2; + if (($srccdom ne $cdom) || ($srccnum ne $cnum)) { + $rewrites->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$ressrc} = $id; + $changed = 1; + } + } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) { + my $srccdom = $1; + my $srccnum = $2; + if (($srccdom ne $cdom) || ($srccnum ne $cnum)) { + $rewrites->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$ressrc} = $id; + $changed = 1; + } } - if ($repstatus eq 'ok') { - print $copiedfile $content; + } elsif ($token->[1] eq 'param') { + my $to = $token->[2]->{'to'}; + if ($to ne '') { + if (ref($params->{$oldurl}{$to}) eq 'ARRAY') { + push (@{$params->{$oldurl}{$to}},$token->[2]->{'name'}); + } else { + @{$params->{$oldurl}{$to}} = ($token->[2]->{'name'}); + } } - close($copiedfile); - } else { - $$message = 'Could not open destination file for '.$filename."<br />\n"; } - } else { - $$message = 'Could not determine name of file for '.$symb."<br />\n"; } - if ($repstatus eq 'ok') { - $content_name = 'resources/'.$count.'/'.$filename; - } - return $content_name; + return $changed; } -sub extract_media { - my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_; - my ($dirpath,$container); - my %allfiles = (); - my %codebase = (); - if ($url =~ m-(.*/)([^/]+)$-) { - $dirpath = $1; - $container = $2; - } else { - $dirpath = $url; - $container = ''; - } - &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content); - foreach my $embed_file (keys(%allfiles)) { - my $filename; - if ($embed_file =~ m#([^/]+)$#) { - $filename = $1; - } else { - $filename = $embed_file; - } - my $newname = 'res/'.$filename; - my ($rtncode,$embed_content,$repstatus); - my $embed_url; - if ($embed_file =~ m-^/-) { - $embed_url = $embed_file; # points to absolute path - } else { - if ($embed_file =~ m-https?://-) { - next; # points to url - } else { - $embed_url = $dirpath.$embed_file; # points to relative path +sub apply_fixups { + my ($is_map,$prefixchg,$cdom,$cnum,$oldurl,$url,$removefrommap,$rewrites, + $retitles,$copies,$dbcopies,$zombies,$params,$docmoves,$mapmoves,$errors, + $before,$after) = @_; + my ($oldsubdir,$newsubdir,$subdirchg); + if ($is_map) { + ($oldsubdir) = + ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_?(\d*)}); + if ($oldsubdir eq '') { + $oldsubdir = 'default'; + } + ($newsubdir) = + ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_?(\d*)}); + if ($newsubdir eq '') { + $newsubdir = 'default'; + } + if ($oldsubdir ne $newsubdir) { + $subdirchg = 1; + } + } + foreach my $key (keys(%{$copies}),keys(%{$docmoves})) { + my @allcopies; + if (ref($copies->{$key}) eq 'HASH') { + my %added; + foreach my $innerkey (keys(%{$copies->{$key}})) { + if (($innerkey ne '') && (!$added{$innerkey})) { + push(@allcopies,$innerkey); + $added{$innerkey} = 1; + } } + undef(%added); } - if ($caller eq 'resource') { - my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res'; - my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url); - $embed_content = &Apache::lonnet::getfile($embed_path); - unless ($embed_content eq -1) { - $repstatus = 'ok'; + if ($key eq $oldurl) { + if ((exists($docmoves->{$key}))) { + unless (grep(/^\Q$oldurl\E/,@allcopies)) { + push(@allcopies,$oldurl); + } } - } elsif ($caller eq 'uploaded') { - - $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode); } - if ($repstatus eq 'ok') { - my $destination = $tempexport.'/resources/'.$count.'/res'; - if (!-e "$destination") { - mkdir($destination,0755); - } - $destination .= '/'.$filename; - my $copiedfile; - if ($copiedfile = Apache::File->new('>'.$destination)) { - print $copiedfile $embed_content; - push @{$href}, 'resources/'.$count.'/res/'.$filename; - my $attrib_regexp = ''; - if (@{$allfiles{$embed_file}} > 1) { - $attrib_regexp = join('|',@{$allfiles{$embed_file}}); - } else { - $attrib_regexp = $allfiles{$embed_file}[0]; - } - $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi; - if ($caller eq 'resource' && $container =~ /\.(problem|library)$/) { - $$content =~ s#\Q$embed_file\E#$newname#gi; + if (@allcopies > 0) { + foreach my $item (@allcopies) { + my ($relpath,$fname) = + ($item =~ m{^(/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(?:default|\d+)/.*/)([^/]+)$}); + if ($fname ne '') { + my $content = &Apache::lonnet::getfile($item); + unless ($content eq '-1') { + my $storefn; + if (($key eq $oldurl) && (ref($docmoves) eq 'HASH') && (exists($docmoves->{$key}))) { + $storefn = $docmoves->{$key}; + } else { + $storefn = $relpath; + $storefn =~s{^/uploaded/$match_domain/$match_courseid/}{}; + if ($prefixchg) { + $storefn =~ s/^\Q$before->{'doc'}\E/$after->{'doc'}/; + } + if (($key eq $oldurl) && ($subdirchg)) { + $storefn =~ s{^(docs|supplemental)/\Q$oldsubdir\E/}{$1/$newsubdir/}; + } + } + ©_dependencies($item,$storefn,$relpath,$errors,\$content); + my $copyurl = + &Apache::lonclonecourse::writefile($env{'request.course.id'}, + $storefn.$fname,$content); + if ($copyurl eq '/adm/notfound.html') { + if ((ref($docmoves) eq 'HASH') && (exists($docmoves->{$oldurl}))) { + return &mt('Paste failed: an error occurred copying the file.'); + } elsif (ref($errors) eq 'HASH') { + $errors->{$item} = 1; + } + } + } } } + } + } + foreach my $key (keys(%{$mapmoves})) { + my $storefn=$key; + $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; + if ($prefixchg) { + $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + } + my $mapcontent = &Apache::lonnet::getfile($key); + if ($mapcontent eq '-1') { + if (ref($errors) eq 'HASH') { + $errors->{$key} = 1; + } } else { - $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode."<br />\n"; + my $newmap = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn, + $mapcontent); + if ($newmap eq '/adm/notfound.html') { + if (ref($errors) eq 'HASH') { + $errors->{$key} = 1; + } + } } } - return; -} - -sub store_template { - my ($contents,$tempexport,$count,$content_type) = @_; - if ($contents) { - if ($tempexport) { - if (!-e $tempexport.'/resources') { - mkdir($tempexport.'/resources',0700); - } - if (!-e $tempexport.'/resources/'.$count) { - mkdir($tempexport.'/resources/'.$count,0700); - } - my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml'; - my $storetemplate; - if ($storetemplate = Apache::File->new('>'.$destination)) { - print $storetemplate $contents; - close($storetemplate); + my %updates; + if ($is_map) { + foreach my $key (keys(%{$rewrites})) { + $updates{$key} = 1; + } + foreach my $key (keys(%{$zombies})) { + $updates{$key} = 1; + } + foreach my $key (keys(%{$removefrommap})) { + $updates{$key} = 1; + } + foreach my $key (keys(%{$dbcopies})) { + $updates{$key} = 1; + } + foreach my $key (keys(%{$retitles})) { + $updates{$key} = 1; + } + foreach my $key (keys(%updates)) { + my (%torewrite,%toretitle,%toremove,%zombie,%newdb); + if (ref($rewrites->{$key}) eq 'HASH') { + %torewrite = %{$rewrites->{$key}}; + } + if (ref($retitles->{$key}) eq 'HASH') { + %toretitle = %{$retitles->{$key}}; + } + if (ref($removefrommap->{$key}) eq 'HASH') { + %toremove = %{$removefrommap->{$key}}; + } + if (ref($zombies->{$key}) eq 'HASH') { + %zombie = %{$zombies->{$key}}; } - if ($content_type eq 'external') { - return 'resources/'.$count.'/'.$content_type.'.html'; + if (ref($dbcopies->{$key}) eq 'HASH') { + foreach my $item (keys(%{$dbcopies->{$key}})) { + $newdb{$item} = &dbcopy($item); + } + } + my $map = &Apache::lonnet::getfile($key); + my $newcontent; + if ($map eq '-1') { + return &mt('Paste failed: an error occurred reading a folder or page: [_1].',$key); } else { - return 'resources/'.$count.'/'.$content_type.'.xml'; + my $parser = HTML::TokeParser->new(\$map); + $parser->attr_encoded(1); + while (my $token = $parser->get_token) { + if ($token->[0] eq 'S') { + if ($token->[2]->{'type'} eq 'zombie') { + next if (($token->[2]->{'src'} ne '') && + ($zombie{$token->[2]->{'src'}} eq $token->[2]->{'id'})); + } + if ($token->[1] eq 'resource') { + my $src = $token->[2]->{'src'}; + my $id = $token->[2]->{'id'}; + my $title = $token->[2]->{'title'}; + my $changed; + if ((exists($toretitle{$src})) && ($toretitle{$src} eq $id)) { + if ($title =~ m{^\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { + $token->[2]->{'title'} = $1; + $changed = 1; + } + } + if ((exists($torewrite{$src})) && ($torewrite{$src} eq $id)) { + $src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/}; + if ($src =~ m{^/uploaded/}) { + if ($prefixchg) { + if ($src =~ /\.(page|sequence)$/) { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'map'}\E#$1$after->{'map'}#; + } else { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'doc'}\E#$1$after->{'doc'}#; + } + } + if (($key eq $oldurl) && ($src !~ /\.(page|sequence)$/) && ($subdirchg)) { + $src =~ s{^(/uploaded/$match_domain/$match_courseid/\w+/)\Q$oldsubdir\E}{$1$newsubdir}; + } + } + $token->[2]->{'src'} = $src; + $changed = 1; + } elsif ($newdb{$src} ne '') { + $token->[2]->{'src'} = $newdb{$src}; + $changed = 1; + } + if ($changed) { + $newcontent .= "<$token->[1]"; + foreach my $attr (@{$token->[3]}) { + if ($attr =~ /^\w+$/) { + $newcontent .= ' '.$attr.'="'.$token->[2]->{$attr}.'"'; + } + } + $newcontent .= ' />'."\n"; + } else { + $newcontent .= $token->[4]."\n"; + } + } elsif (($token->[2]->{'id'} ne '') && + (exists($toremove{$token->[2]->{'id'}}))) { + next; + } else { + $newcontent .= $token->[4]."\n"; + } + } elsif ($token->[0] eq 'E') { + $newcontent .= $token->[2]."\n"; + } + } + } + my $storefn; + if ($key eq $oldurl) { + $storefn = $url; + $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; + } else { + $storefn = $key; + $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; + if ($prefixchg) { + $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + } + } + my $newmapurl = + &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn, + $newcontent); + if ($newmapurl eq '/adm/notfound.html') { + return &mt('Paste failed: an error occurred saving the folder or page.'); } } } + return 'ok'; } -# Imports the given (name, url) resources into the course -# coursenum, coursedom, and folder must precede the list -sub group_import { - my $coursenum = shift; - my $coursedom = shift; - my $folder = shift; - my $container = shift; - my $caller = shift; - while (@_) { - my $name = shift; - my $url = shift; - if (($url =~ m#^/uploaded/$coursedom/$coursenum/(default_\d+\.)(page|sequence)$#) && ($caller eq 'londocs')) { - my $errtext = ''; - my $fatal = 0; - my $newmapstr = '<map>'."\n". - '<resource id="1" src="" type="start"></resource>'."\n". - '<link from="1" to="2" index="1"></link>'."\n". - '<resource id="2" src="" type="finish"></resource>'."\n". - '</map>'; - $env{'form.output'}=$newmapstr; - my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, - 'output',$1.$2); - if ($result != m|^/uploaded/|) { - $errtext.='Map not saved: A network error occured when trying to save the new map. '; - $fatal = 2; - } - if ($fatal) { - return ($errtext,$fatal); +sub copy_dependencies { + my ($item,$storefn,$relpath,$errors,$contentref) = @_; + my $content; + if (ref($contentref)) { + $content = $$contentref; + } else { + $content = &Apache::lonnet::getfile($item); + } + unless ($content eq '-1') { + my $mm = new File::MMagic; + my $mimetype = $mm->checktype_contents($content); + if ($mimetype eq 'text/html') { + my (%allfiles,%codebase,$state); + my $res = &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,\$content); + if ($res eq 'ok') { + my ($numexisting,$numpathchanges,$existing); + (undef,$numexisting,$numpathchanges,$existing) = + &Apache::loncommon::ask_for_embedded_content( + '/adm/coursedocs',$state,\%allfiles,\%codebase, + {'error_on_invalid_names' => 1, + 'ignore_remote_references' => 1, + 'docs_url' => $item, + 'context' => 'paste'}); + if ($numexisting > 0) { + if (ref($existing) eq 'HASH') { + foreach my $dep (keys(%{$existing})) { + my $depfile = $dep; + unless ($depfile =~ m{^\Q$relpath\E}) { + $depfile = $relpath.$dep; + } + my $depcontent = &Apache::lonnet::getfile($depfile); + unless ($depcontent eq '-1') { + my $storedep = $dep; + $storedep =~ s{^\Q$relpath\E}{}; + my $dep_url = + &Apache::lonclonecourse::writefile( + $env{'request.course.id'}, + $storefn.$storedep,$depcontent); + if ($dep_url eq '/adm/notfound.html') { + if (ref($errors) eq 'HASH') { + $errors->{$depfile} = 1; + } + } else { + ©_dependencies($depfile,$storefn,$relpath,$errors,\$depcontent); + } + } + } + } + } } } - if ($url) { - my $idx = &Apache::lonratedt::getresidx($url); - $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=$idx; - my $ext = 'false'; - if ($url=~/^http:\/\//) { $ext = 'true'; } - $url =~ s/:/\:/g; - $name =~ s/:/\:/g; - $Apache::lonratedt::resources[$idx] = - join ':', ($name, $url, $ext, 'normal', 'res'); - } } - return &storemap($coursenum, $coursedom, $folder.'.'.$container); + return; } -sub breadcrumbs { - my ($where)=@_; - &Apache::lonhtmlcommon::clear_breadcrumbs(); - my (@folders); - if ($env{'form.pagepath'}) { - @folders = split('&',$env{'form.pagepath'}); +my %parameter_type = ( 'randompick' => 'int_pos', + 'hiddenresource' => 'string_yesno', + 'encrypturl' => 'string_yesno', + 'randomorder' => 'string_yesno',); +my $valid_parameters_re = join('|',keys(%parameter_type)); +# set parameters +sub update_parameter { + + return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/); + + my $which = $env{'form.changeparms'}; + my $idx = $env{'form.setparms'}; + if ($env{'form.'.$which.'_'.$idx}) { + my $value = ($which eq 'randompick') ? $env{'form.'.$which.'_'.$idx} + : 'yes'; + &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value, + $parameter_type{$which}); + &remember_parms($idx,$which,'set',$value); } else { - @folders=split('&',$env{'form.folderpath'}); - } - my $folderpath; - my $cpinfo=''; - if ($env{'form.markedcopy_url'}) { - $cpinfo='&markedcopy_url='. - &escape($env{'form.markedcopy_url'}). - '&markedcopy_title='. - &escape($env{'form.markedcopy_title'}); + &LONCAPA::map::delparameter($idx,'parameter_'.$which); + + &remember_parms($idx,$which,'del'); } - while (@folders) { - my $folder=shift(@folders); - my $foldername=shift(@folders); - if ($folderpath) {$folderpath.='&';} - $folderpath.=$folder.'&'.$foldername; - my $url='/adm/coursedocs?folderpath='. - &escape($folderpath); - &Apache::lonhtmlcommon::add_breadcrumb( - {'href'=>$url.$cpinfo, - 'title'=>&unescape($foldername), - 'text'=>'<font size="+1">'. - &unescape($foldername).'</font>' - }); - - + return 1; +} + + +sub handle_edit_cmd { + my ($coursenum,$coursedom) =@_; + my ($cmd,$idx)=split('_',$env{'form.cmd'}); + + my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]; + my ($title, $url, @rrest) = split(':', $ratstr); + + if ($cmd eq 'del') { + if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && + ($url!~/$LONCAPA::assess_page_seq_re/)) { + &Apache::lonnet::removeuploadedurl($url); + } else { + &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]); + } + splice(@LONCAPA::map::order, $idx, 1); + + } elsif ($cmd eq 'cut') { + &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]); + splice(@LONCAPA::map::order, $idx, 1); + + } elsif ($cmd eq 'up' + && ($idx) && (defined($LONCAPA::map::order[$idx-1]))) { + @LONCAPA::map::order[$idx-1,$idx] = @LONCAPA::map::order[$idx,$idx-1]; + + } elsif ($cmd eq 'down' + && defined($LONCAPA::map::order[$idx+1])) { + @LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1]; + + } elsif ($cmd eq 'rename') { + + my $comment = &LONCAPA::map::qtunescape($env{'form.title'}); + if ($comment=~/\S/) { + $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]= + $comment.':'.join(':', $url, @rrest); + } +# Devalidate title cache + my $renamed_url=&LONCAPA::map::qtescape($url); + &Apache::lonnet::devalidate_title_cache($renamed_url); + } else { + return 0; } - return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp', - 'LC_docs_path'); + return 1; } sub editor { - my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output)=@_; - my $errtext=''; - my $fatal=0; - my $container='sequence'; - if ($env{'form.pagepath'}) { - $container='page'; + my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype, + $supplementalflag,$orderhash,$iconpath)=@_; + my $container= ($env{'form.pagepath'}) ? 'page' + : 'sequence'; + + my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = + &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail); + + my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; + + unless ($allowed) { + $randompick = -1; } - ($errtext,$fatal)= - &mapread($coursenum,$coursedom,$folder.'.'.$container); - if ($#Apache::lonratedt::order<1) { - my $idx=&Apache::lonratedt::getresidx(); + + my ($errtext,$fatal) = &mapread($coursenum,$coursedom, + $folder.'.'.$container); + return $errtext if ($fatal); + + if ($#LONCAPA::map::order<1) { + my $idx=&LONCAPA::map::getresidx(); if ($idx<=0) { $idx=1; } - $Apache::lonratedt::order[0]=$idx; - $Apache::lonratedt::resources[$idx]=''; - } - if (defined($env{'form.markcopy'})) { -# Mark for copying - my ($title,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$env{'form.markcopy'}]]); - $env{'form.markedcopy_title'}=$title; - $env{'form.markedcopy_url'}=$url; + $LONCAPA::map::order[0]=$idx; + $LONCAPA::map::resources[$idx]=''; } - $r->print(&breadcrumbs($folder)); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - } else { + # ------------------------------------------------------------ Process commands # ---------------- if they are for this folder and user allowed to make changes - if (($allowed) && ($env{'form.folder'} eq $folder)) { + if (($allowed) && ($env{'form.folder'} eq $folder)) { # set parameters and change order - if (defined($env{'form.setparms'})) { - my $idx=$env{'form.setparms'}; -# set parameters - if ($env{'form.randpick_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_randompick',$env{'form.randpick_'.$idx},'int_pos'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_randompick'); - } - if ($env{'form.hidprs_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_hiddenresource'); - } - if ($env{'form.encprs_'.$idx}) { - &Apache::lonratedt::storeparameter($idx,'parameter_encrypturl','yes','string_yesno'); - } else { - &Apache::lonratedt::delparameter($idx,'parameter_encrypturl'); - } + &snapshotbefore(); + + if (&update_parameter()) { + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + return $errtext if ($fatal); + } - if ($env{'form.newpos'}) { + if ($env{'form.newpos'} && $env{'form.currentpos'}) { # change order + my $res = splice(@LONCAPA::map::order,$env{'form.currentpos'}-1,1); + splice(@LONCAPA::map::order,$env{'form.newpos'}-1,0,$res); - my $newpos=$env{'form.newpos'}-1; - my $currentpos=$env{'form.currentpos'}-1; - my $i; - my @neworder=(); - if ($newpos>$currentpos) { -# moving stuff up - for ($i=0;$i<$currentpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - for ($i=$currentpos;$i<$newpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i+1]; - } - $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; - for ($i=$newpos+1;$i<=$#Apache::lonratedt::order;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - } else { -# moving stuff down - for ($i=0;$i<$newpos;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; - for ($i=$newpos+1;$i<$currentpos+1;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i-1]; - } - for ($i=$currentpos+1;$i<=$#Apache::lonratedt::order;$i++) { - $neworder[$i]=$Apache::lonratedt::order[$i]; - } - } - @Apache::lonratedt::order=@neworder; - } -# store the changed version + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + return $errtext if ($fatal); + } - ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - return; - } - - } - if ($env{'form.pastemarked'}) { -# paste resource to end of list - my $url=$env{'form.markedcopy_url'}; - my $title=$env{'form.markedcopy_title'}; -# Maps need to be copied first - if (($url=~/\.(page|sequence)$/) || ($url=~/^\/uploaded\//)) { - $title=&mt('Copy of').' '.$title; - my $newid=$$.time; - $url=~/^(.+)\.(\w+)$/; - my $newurl=$1.$newid.'.'.$2; - my $storefn=$newurl; - $storefn=~s/^\/\w+\/\w+\/\w+\///; - &Apache::loncreatecourse::writefile - ($env{'request.course.id'},$storefn, - &Apache::lonnet::getfile($url)); - $url=$newurl; - } - $title=~s/\</\<\;/g; - $title=~s/\>/\>\;/g; - $title=~s/\:/\:/g; - my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; -# Now insert the URL at the bottom - my $newidx=&Apache::lonratedt::getresidx($url); - $Apache::lonratedt::resources[$newidx]= - $title.':'.$url.':'.$ext.':normal:res'; - $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx; + if ($env{'form.pastemarked'}) { + my %paste_errors; + my $paste_res = + &do_paste_from_buffer($coursenum,$coursedom,$folder,\%paste_errors); + if ($paste_res eq 'ok') { # Store the result - ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - return; - } - - } - $r->print($upload_output); - if ($env{'form.cmd'}) { - my ($cmd,$idx)=split(/\_/,$env{'form.cmd'}); - if ($cmd eq 'del') { - my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); - if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && - ($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) { - &Apache::lonnet::removeuploadedurl($url); - } else { - &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); - } - for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { - $Apache::lonratedt::order[$i]= - $Apache::lonratedt::order[$i+1]; - } - $#Apache::lonratedt::order--; - } elsif ($cmd eq 'cut') { - my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); - &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); - for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { - $Apache::lonratedt::order[$i]= - $Apache::lonratedt::order[$i+1]; - } - $#Apache::lonratedt::order--; - } elsif ($cmd eq 'up') { - if (($idx) && (defined($Apache::lonratedt::order[$idx-1]))) { - my $i=$Apache::lonratedt::order[$idx-1]; - $Apache::lonratedt::order[$idx-1]= - $Apache::lonratedt::order[$idx]; - $Apache::lonratedt::order[$idx]=$i; - } - } elsif ($cmd eq 'down') { - if (defined($Apache::lonratedt::order[$idx+1])) { - my $i=$Apache::lonratedt::order[$idx+1]; - $Apache::lonratedt::order[$idx+1]= - $Apache::lonratedt::order[$idx]; - $Apache::lonratedt::order[$idx]=$i; - } - } elsif ($cmd eq 'rename') { - my $ratstr = $Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]; - my ($rtitle,@rrest)=split(/\:/, - $Apache::lonratedt::resources[ - $Apache::lonratedt::order[$idx]]); - my $comment= - &HTML::Entities::decode($env{'form.title'}); - $comment=~s/\</\<\;/g; - $comment=~s/\>/\>\;/g; - $comment=~s/\:/\:/g; - if ($comment=~/\S/) { - $Apache::lonratedt::resources[ - $Apache::lonratedt::order[$idx]]= - $comment.':'.join(':',@rrest); - } -# Devalidate title cache - &Apache::lonnet::devalidate_title_cache(&Apache::lonnet::unescape($rrest[0])); + ($errtext,$fatal) = &storemap($coursenum,$coursedom,$folder.'.'.$container); + return $errtext if ($fatal); + } elsif ($paste_res ne '') { + $r->print('<p><span class="LC_error">'.$paste_res.'</span></p>'); + } + if (keys(%paste_errors) > 0) { + $r->print('<p span class="LC_warning">'."\n". + &mt('The following files are either dependencies of a web page or references within a folder and/or composite page which could not be copied during the paste operation:')."\n". + '<ul>'."\n"); + foreach my $key (sort(keys(%paste_errors))) { + $r->print('<li>'.$key.'</li>'."\n"); } -# Store the changed version - ($errtext,$fatal)=&storemap($coursenum,$coursedom, - $folder.'.'.$container); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - return; - } + $r->print('</ul></p>'."\n"); } + } + + $r->print($upload_output); + + if (&handle_edit_cmd()) { + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + return $errtext if ($fatal); + } # Group import/search - if ($env{'form.importdetail'}) { - my @imports; - &Apache::lonnet::logthis("imp detail ".$env{'form.importdetail'}); - foreach (split(/\&/,$env{'form.importdetail'})) { - if (defined($_)) { - my ($name,$url)=split(/\=/,$_); - $name=&unescape($name); - $url=&unescape($url); - push @imports, $name, $url; - } - } -# Store the changed version - ($errtext,$fatal)=group_import($coursenum, $coursedom, $folder, - $container,'londocs',@imports); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - return; + if ($env{'form.importdetail'}) { + my @imports; + foreach my $item (split(/\&/,$env{'form.importdetail'})) { + if (defined($item)) { + my ($name,$url,$residx)= + map {&unescape($_)} split(/\=/,$item); + push(@imports, [$name, $url, $residx]); } - } + } + ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder, + $container,'londocs',@imports); + return $errtext if ($fatal); + } # Loading a complete map - if ($env{'form.loadmap'}) { - if ($env{'form.importmap'}=~/\w/) { - foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) { - my ($title,$url,$ext,$type)=split(/\:/,$_); - my $idx=&Apache::lonratedt::getresidx($url); - $Apache::lonratedt::resources[$idx]=$_; - $Apache::lonratedt::order - [$#Apache::lonratedt::order+1]=$idx; - } -# Store the changed version - ($errtext,$fatal)=&storemap($coursenum,$coursedom, - $folder.'.'.$container); - if ($fatal) { - $r->print('<p><font color="red">'.$errtext.'</font></p>'); - return; - } - } else { - $r->print('<p><font color="red">'.&mt('No map selected.').'</font></p>'); - } - } - } + if ($env{'form.loadmap'}) { + if ($env{'form.importmap'}=~/\w/) { + foreach my $res (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) { + my ($title,$url,$ext,$type)=split(/\:/,$res); + my $idx=&LONCAPA::map::getresidx($url); + $LONCAPA::map::resources[$idx]=$res; + $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx; + } + ($errtext,$fatal)=&storemap($coursenum,$coursedom, + $folder.'.'.$container); + return $errtext if ($fatal); + } else { + $r->print('<p><span class="LC_error">'.&mt('No map selected.').'</span></p>'); + + } + } + &log_differences($plain); + } # ---------------------------------------------------------------- End commands # ---------------------------------------------------------------- Print screen - my $idx=0; - my $shown=0; - $r->print('<table>'); - foreach (@Apache::lonratedt::order) { - my ($name,$url)=split(/\:/,$Apache::lonratedt::resources[$_]); - $name=&Apache::lonratsrv::qtescape($name); - $url=&Apache::lonratsrv::qtescape($url); - unless ($name) { $name=(split(/\//,$url))[-1]; } - unless ($name) { $idx++; next; } - $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum)); - $idx++; - $shown++; - } - unless ($shown) { - $r->print('<tr><td>'.&mt('Currently no documents.').'</td></tr>'); - } - $r->print("\n</table>\n"); - if ($env{'form.markedcopy_url'}) { - $r->print(<<ENDPASTE); -<p><form name="pasteform" action="/adm/coursedocs" method="post"> -<input type="hidden" name="markedcopy_url" value="$env{'form.markedcopy_url'}" /> -<input type="hidden" name="markedcopy_title" value="$env{'form.markedcopy_title'}" /> -ENDPASTE + my $idx=0; + my $shown=0; + if (($ishidden) || ($isencrypted) || ($randompick>=0) || ($is_random_order)) { + $r->print('<div class="LC_Box">'. + '<ol class="LC_docs_parameters"><li class="LC_docs_parameters_title">'.&mt('Parameters:').'</li>'. + ($randompick>=0?'<li>'.&mt('randomly pick [quant,_1,resource]',$randompick).'</li>':''). + ($ishidden?'<li>'.&mt('contents hidden').'</li>':''). + ($isencrypted?'<li>'.&mt('URLs hidden').'</li>':''). + ($is_random_order?'<li>'.&mt('random order').'</li>':''). + '</ol>'); + if ($randompick>=0) { + $r->print('<p class="LC_warning">' + .&mt('Caution: this folder is set to randomly pick a subset' + .' of resources. Adding or removing resources from this' + .' folder will change the set of resources that the' + .' students see, resulting in spurious or missing credit' + .' for completed problems, not limited to ones you' + .' modify. Do not modify the contents of this folder if' + .' it is in active student use.') + .'</p>' + ); + } + if ($is_random_order) { + $r->print('<p class="LC_warning">' + .&mt('Caution: this folder is set to randomly order its' + .' contents. Adding or removing resources from this folder' + .' will change the order of resources shown.') + .'</p>' + ); + } + $r->print('</div>'); + } + + my ($to_show,$output); + + &Apache::loncommon::start_data_table_count(); #setup a row counter + foreach my $res (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); + $name=&LONCAPA::map::qtescape($name); + $url=&LONCAPA::map::qtescape($url); + unless ($name) { $name=(split(/\//,$url))[-1]; } + unless ($name) { $idx++; next; } + $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, + $coursenum,$crstype); + $idx++; + $shown++; + } + &Apache::loncommon::end_data_table_count(); + + if ($shown) { + $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll') + .&Apache::loncommon::start_data_table(undef,'contentlist'); + if ($allowed) { + $to_show .= &Apache::loncommon::start_data_table_header_row() + .'<th colspan="2">'.&mt('Move').'</th>' + .'<th>'.&mt('Actions').'</th>' + .'<th colspan="2">'.&mt('Document').'</th>'; + if ($folder !~ /^supplemental/) { + $to_show .= '<th colspan="4">'.&mt('Settings').'</th>'; + } + $to_show .= &Apache::loncommon::end_data_table_header_row(); + } + $to_show .= $output.' ' + .&Apache::loncommon::end_data_table() + .'<br style="line-height:2px;" />' + .&Apache::loncommon::end_scrollbox(); + } else { + $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll') + .'<div class="LC_info" id="contentlist">' + .&mt('Currently no documents.') + .'</div>' + .&Apache::loncommon::end_scrollbox(); + } + my $tid = 1; + if ($supplementalflag) { + $tid = 2; + } + if ($allowed) { + my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; + $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto, + $readfile)); + &print_paste_buffer($r,$container,$folder); + } else { + if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { + #Function Box for Supplemental Content for users with mdc priv. + my $funcname = &mt('Folder Editor'); $r->print( - '<input type="submit" name="pastemarked" value="'.&mt('Paste'). - '" /> '.&Apache::loncommon::filedescription( - (split(/\./,$env{'form.markedcopy_url'}))[-1]).': '. - $env{'form.markedcopy_title'}); - if ($container eq 'page') { - $r->print(<<PAGEINFO); -<input type="hidden" name="pagepath" value="$env{'form.pagepath'}" /> -<input type="hidden" name="pagesymb" value="$env{'form.pagesymb'}" /> -PAGEINFO - } else { - $r->print(<<FOLDERINFO); -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -FOLDERINFO - } - $r->print('</form></p>'); - } + &Apache::loncommon::head_subbox( + &Apache::lonhtmlcommon::start_funclist(). + &Apache::lonhtmlcommon::add_item_funclist( + '<a href="/adm/coursedocs?command=direct&forcesupplement=1&'. + 'supppath='.&HTML::Entities::encode($env{'form.folderpath'}).'">'. + '<img src="/res/adm/pages/docs.png" alt="'.$funcname.'" class="LC_icon" />'. + '<span class="LC_menubuttons_inline_text">'.$funcname.'</span></a>'). + &Apache::lonhtmlcommon::end_funclist())); + } + $r->print($to_show); } + return; } sub process_file_upload { my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_; # upload a file, if present - my $parseaction; - if ($env{'form.parserflag'}) { + my ($parseaction,$showupload,$nextphase,$mimetype); + if ($env{'form.parserflag'}) { $parseaction = 'parse'; } - my $phase_status; my $folder=$env{'form.folder'}; if ($folder eq '') { $folder='default'; @@ -1282,12 +1678,13 @@ sub process_file_upload { } ($errtext,$fatal)= &mapread($coursenum,$coursedom,$folder.'.'.$container); - if ($#Apache::lonratedt::order<1) { - $Apache::lonratedt::order[0]=1; - $Apache::lonratedt::resources[1]=''; + if ($#LONCAPA::map::order<1) { + $LONCAPA::map::order[0]=1; + $LONCAPA::map::resources[1]=''; } if ($fatal) { - return 'failed'; + $$upload_output = '<div class="LC_error" id="uploadfileresult">'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'</div>'; + return; } my $destination = 'docs/'; if ($folder =~ /^supplemental/) { @@ -1298,157 +1695,180 @@ sub process_file_upload { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } -# this is for a course, not a user, so set coursedoc flag -# probably the only place in the system where this should be "1" - my $newidx=&Apache::lonratedt::getresidx(); +# this is for a course, not a user, so set context to coursedoc. + my $newidx=&LONCAPA::map::getresidx(); $destination .= $newidx; - my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination, + my $url=&Apache::lonnet::userfileupload('uploaddoc','coursedoc',$destination, $parseaction,$allfiles, - $codebase); + $codebase,undef,undef,undef,undef, + undef,undef,\$mimetype); + if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E.*/([^/]+)$}) { + my $stored = $1; + $showupload = '<p>'.&mt('Uploaded [_1]','<span class="LC_filename">'. + $stored.'</span>').'</p>'; + } else { + my ($filename) = ($env{'form.uploaddoc.filename'} =~ m{([^/]+)$}); + + $$upload_output = '<div class="LC_error" id="uploadfileresult">'.&mt('Unable to save file [_1].','<span class="LC_filename">'.$filename.'</span>').'</div>'; + return; + } my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; + if ($url=~m{^http://}) { $ext='true'; } + $url = &LONCAPA::map::qtunescape($url); my $comment=$env{'form.comment'}; - $comment=~s/\</\<\;/g; - $comment=~s/\>/\>\;/g; - $comment=~s/\:/\:/g; + $comment = &LONCAPA::map::qtunescape($comment); if ($folder=~/^supplemental/) { $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'. $env{'user.domain'}.'___&&&___'.$comment; } - $Apache::lonratedt::resources[$newidx]= - $comment.':'.$url.':'.$ext.':normal:res'; - $Apache::lonratedt::order[$#Apache::lonratedt::order+1]= $newidx; + $LONCAPA::map::resources[$newidx]= + $comment.':'.$url.':'.$ext.':normal:res'; + $LONCAPA::map::order[$#LONCAPA::map::order+1]= $newidx; ($errtext,$fatal)=&storemap($coursenum,$coursedom, $folder.'.'.$container); if ($fatal) { - $$upload_output .= '<p><font color="red">'.$errtext.'</font></p>'; - return 'failed'; + $$upload_output = '<div class="LC_error" id="uploadfileresult">'.$errtext.'</div>'; + return; } else { - if ($parseaction eq 'parse') { - my $total_embedded = keys(%{$allfiles}); + if ($parseaction eq 'parse' && $mimetype eq 'text/html') { + $$upload_output = $showupload; + my $total_embedded = scalar(keys(%{$allfiles})); if ($total_embedded > 0) { - my $num = 0; - $$upload_output .= 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br /> - <form name="upload_embedded" action="/adm/coursedocs" - method="post" enctype="multipart/form-data"> - <input type="hidden" name="folderpath" value="'.$env{'form.folderpath'}.'" /> <input type="hidden" name="cmd" value="upload_embedded" /> - <input type="hidden" name="newidx" value="'.$newidx.'" /> - <input type="hidden" name="primaryurl" value="'.&escape($url).'" /> - <input type="hidden" name="phasetwo" value="'.$total_embedded.'" />'; - $$upload_output .= '<b>Upload embedded files</b>:<br /> - <table>'; - foreach my $embed_file (keys(%{$allfiles})) { - $$upload_output .= '<tr><td>'.$embed_file. - '<input name="embedded_item_'.$num.'" type="file" /> - <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />'; - my $attrib; - if (@{$$allfiles{$embed_file}} > 1) { - $attrib = join(':',@{$$allfiles{$embed_file}}); + my $uploadphase = 'upload_embedded'; + my $primaryurl = &HTML::Entities::encode($url,'<>&"'); + my $state = &embedded_form_elems($uploadphase,$primaryurl,$newidx); + my ($embedded,$num) = + &Apache::loncommon::ask_for_embedded_content( + '/adm/coursedocs',$state,$allfiles,$codebase,{'docs_url' => $url}); + if ($embedded) { + if ($num) { + $$upload_output .= + '<p>'.&mt('This file contains embedded multimedia objects, which need to be uploaded.').'</p>'.$embedded; + $nextphase = $uploadphase; } else { - $attrib = $$allfiles{$embed_file}[0]; - } - $$upload_output .= - '<input name="embedded_attrib_'.$num.'" type="hidden" value="'.$attrib.'" />'; - if (exists($$codebase{$embed_file})) { - $$upload_output .= - '<input name="codebase_'.$num.'" type="hidden" value="'.&escape($$codebase{$embed_file}).'" />'; + $$upload_output .= $embedded; } - $$upload_output .= '</td></tr>'; - $num ++; + } else { + $$upload_output .= &mt('Embedded item(s) already present, so no additional upload(s) required').'<br />'; } - $phase_status = 'phasetwo'; - $$upload_output .= '</table><br /> - <input type ="submit" value="Complete upload" /> - </form>'; } else { - $$upload_output .= 'No embedded items identified<br />'; + $$upload_output .= &mt('No embedded items identified').'<br />'; } + $$upload_output = '<div id="uploadfileresult">'.$$upload_output.'</div>'; + } elsif (&Apache::loncommon::is_archive_file($mimetype)) { + $nextphase = 'decompress_uploaded'; + my $position = scalar(@LONCAPA::map::order)-1; + my $noextract = &return_to_editor(); + my $archiveurl = &HTML::Entities::encode($url,'<>&"'); + my %archiveitems = ( + folderpath => $env{'form.folderpath'}, + pagepath => $env{'form.pagepath'}, + cmd => $nextphase, + newidx => $newidx, + position => $position, + phase => $nextphase, + comment => $comment, + ); + my ($destination,$dir_root) = &embedded_destination($coursenum,$coursedom); + my @current = &get_dir_list($url,$coursenum,$coursedom,$newidx); + $$upload_output = $showupload. + &Apache::loncommon::decompress_form($mimetype, + $archiveurl,'/adm/coursedocs',$noextract, + \%archiveitems,\@current); } } } - return $phase_status; + return $nextphase; } -sub process_secondary_uploads { - my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_; - my $folder=$env{'form.folder'}; - my $destination = 'docs/'; - if ($folder =~ /^supplemental/) { - $destination = 'supplemental/'; - } - if (($folder eq 'default') || ($folder eq 'supplemental')) { - $destination .= 'default/'; - } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { - $destination .= $2.'/'; +sub get_dir_list { + my ($url,$coursenum,$coursedom,$newidx) = @_; + my ($destination,$dir_root) = &embedded_destination(); + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist("$dir_root/$destination/$newidx",$coursedom,$coursenum,1); + my @dir_lines; + my $dirptr=16384; + if (ref($dirlistref) eq 'ARRAY') { + foreach my $dir_line (sort + { + my ($afile)=split('&',$a,2); + my ($bfile)=split('&',$b,2); + return (lc($afile) cmp lc($bfile)); + } (@{$dirlistref})) { + my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16); + $filename =~ s/\s+$//; + next if ($filename =~ /^\.\.?$/); + my $isdir = 0; + if ($dirptr&$testdir) { + $isdir = 1; + } + push(@dir_lines, [$filename,$dom,$isdir,$size,$mtime,$obs]); + } } - $destination .= $newidx; - my ($url,$filename); - $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination); - ($filename) = ($url =~ m-^/uploaded/$coursedom/$coursenum/$destination/(.+)$-); - return $filename; + return @dir_lines; +} + +sub is_supplemental_title { + my ($title) = @_; + return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/); } # --------------------------------------------------------------- An entry line sub entryline { - my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_; - $title=~s/\&colon\;/\:/g; - $title=&HTML::Entities::encode(&HTML::Entities::decode( - &unescape($title)),'"<>&\''); - my $renametitle=$title; - my $foldertitle=$title; - my $pagetitle=$title; - my $orderidx=$Apache::lonratedt::order[$index]; - if ($title=~ /^(\d+)___&&&___(\w+)___&&&___(\w+)___&&&___(.*)$/ ) { - $foldertitle=&Apache::lontexconvert::msgtexconverted($4); - $renametitle=$4; - $title='<i>'.&Apache::lonlocal::locallocaltime($1).'</i> '. - &Apache::loncommon::plainname($2,$3).': <br />'. - $foldertitle; + my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$crstype)=@_; + my ($foldertitle,$pagetitle,$renametitle); + if (&is_supplemental_title($title)) { + ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); + $pagetitle = $foldertitle; + } else { + $title=&HTML::Entities::encode($title,'"<>&\''); + $renametitle=$title; + $foldertitle=$title; + $pagetitle=$title; } + + my $orderidx=$LONCAPA::map::order[$index]; + + $renametitle=~s/\\/\\\\/g; $renametitle=~s/\"\;/\\\"/g; - my $line='<tr>'; + $renametitle=~s/ /%20/g; + my $line=&Apache::loncommon::start_data_table_row(); + my ($form_start,$form_end,$form_common); # Edit commands - my $container; - my $folderpath; + my ($container, $type, $esc_path, $path, $symb); if ($env{'form.folderpath'}) { + $type = 'folder'; $container = 'sequence'; - $folderpath=&escape($env{'form.folderpath'}); + $esc_path=&escape($env{'form.folderpath'}); + $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"'); } - my ($pagepath,$pagesymb); if ($env{'form.pagepath'}) { - $container = 'page'; - $pagepath=&escape($env{'form.pagepath'}); - $pagesymb=&escape($env{'form.pagesymb'}); + $type = $container = 'page'; + $esc_path=&escape($env{'form.pagepath'}); + $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"'); + $symb=&escape($env{'form.pagesymb'}); } my $cpinfo=''; - if ($env{'form.markedcopy_url'}) { - $cpinfo='&markedcopy_url='. - &escape($env{'form.markedcopy_url'}). - '&markedcopy_title='. - &escape($env{'form.markedcopy_title'}); - } if ($allowed) { my $incindex=$index+1; my $selectbox=''; - if (($folder!~/^supplemental/) && - ($#Apache::lonratedt::order>0) && + if (($#LONCAPA::map::order>0) && ((split(/\:/, - $Apache::lonratedt::resources[$Apache::lonratedt::order[0]]))[1] - ne '') && + $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1] + ne '') && ((split(/\:/, - $Apache::lonratedt::resources[$Apache::lonratedt::order[1]]))[1] + $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1] ne '')) { $selectbox= '<input type="hidden" name="currentpos" value="'.$incindex.'" />'. - '<select name="newpos" onChange="this.form.submit()">'; - for (my $i=1;$i<=$#Apache::lonratedt::order+1;$i++) { + '<select name="newpos" onchange="this.form.submit()">'; + for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) { if ($i==$incindex) { - $selectbox.='<option value="" selected="1">('.$i.')</option>'; + $selectbox.='<option value="" selected="selected">('.$i.')</option>'; } else { $selectbox.='<option value="'.$i.'">'.$i.'</option>'; } @@ -1463,80 +1883,87 @@ sub entryline { 'rn' => 'Rename', 'cp' => 'Copy'); my $nocopy=0; + my $nocut=0; if ($url=~/\.(page|sequence)$/) { - foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url))) { - my ($title,$url,$ext,$type)=split(/\:/,$_); - if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) { - $nocopy=1; - last; + if ($url =~ m{/res/}) { + # no copy for published maps + $nocopy = 1; + } else { + foreach my $item (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url),1)) { + my ($title,$url,$ext,$type)=split(/\:/,$item); + if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) { + $nocopy=1; + last; + } } } } + if ($url=~/^\/res\/lib\/templates\//) { + $nocopy=1; + $nocut=1; + } my $copylink=' '; - if ($env{'form.pagepath'}) { - unless ($nocopy) { - $copylink=(<<ENDCOPY); -<a href='javascript:markcopy("$pagepath","$index","$renametitle","page","$pagesymb");'> -<font size="-2" color="#000099">$lt{'cp'}</font></a></td> + my $cutlink=' '; + + my $skip_confirm = 0; + if ( $folder =~ /^supplemental/ + || ($url =~ m{( /smppg$ + |/syllabus$ + |/aboutme$ + |/navmaps$ + |/bulletinboard$ + |\.html$ + |^/adm/wrapper/ext)}x)) { + $skip_confirm = 1; + } + + if (!$nocopy) { + $copylink=(<<ENDCOPY); +<a href="javascript:markcopy('$esc_path','$index','$renametitle','$container','$symb','$folder');" class="LC_docs_copy">$lt{'cp'}</a> ENDCOPY - } - $line.=(<<END); -<form name="entry_$index" action="/adm/coursedocs" method="post"> -<input type="hidden" name="pagepath" value="$env{'form.pagepath'}" /> -<input type="hidden" name="pagesymb" value="$env{'form.pagesymb'}" /> -<input type="hidden" name="markedcopy_url" value="$env{'form.markedcopy_url'}" /> -<input type="hidden" name="markedcopy_title" value="$env{'form.markedcopy_title'}" /> -<input type="hidden" name="setparms" value="$orderidx" /> -<td><table border='0' cellspacing='2' cellpadding='0'> -<tr><td bgcolor="#DDDDDD"> -<a href='/adm/coursedocs?cmd=up_$index&pagepath=$pagepath&pagesymb=$pagesymb$cpinfo'> -<img src="${iconpath}move_up.gif" alt='$lt{'up'}' border='0' /></a></td></tr> -<tr><td bgcolor="#DDDDDD"> -<a href='/adm/coursedocs?cmd=down_$index&pagepath=$pagepath&pagesymb=$pagesymb$cpinfo'> -<img src="${iconpath}move_down.gif" alt='$lt{'dw'}' border='0' /></a></td></tr> -</table></td> -<td>$selectbox -</td><td bgcolor="#DDDDDD"> -<a href='javascript:removeres("$pagepath","$index","$renametitle","page","$pagesymb");'> -<font size="-2" color="#990000">$lt{'rm'}</font></a> -<a href='javascript:cutres("$pagepath","$index","$renametitle","page","$pagesymb");'> -<font size="-2" color="#550044">$lt{'ct'}</font></a> -<a href='javascript:changename("$pagepath","$index","$renametitle","page","$pagesymb");'> -<font size="-2" color="#009900">$lt{'rn'}</font></a> -$copylink + } + if (!$nocut) { + $cutlink=(<<ENDCUT); +<a href="javascript:cutres('$esc_path','$index','$renametitle','$container','$symb','$folder',$skip_confirm);" class="LC_docs_cut">$lt{'ct'}</a> +ENDCUT + } + $form_start = ' + <form action="/adm/coursedocs" method="post"> +'; + $form_common=(<<END); + <input type="hidden" name="${type}path" value="$path" /> + <input type="hidden" name="${type}symb" value="$symb" /> + <input type="hidden" name="setparms" value="$orderidx" /> + <input type="hidden" name="changeparms" value="0" /> END - } else { - unless ($nocopy) { - $copylink=(<<ENDCOPY); -<a href='javascript:markcopy("$folderpath","$index","$renametitle","sequence");'> -<font size="-2" color="#000099">$lt{'cp'}</font></a></td> -ENDCOPY - } - $line.=(<<END); -<form name="entry_$index" action="/adm/coursedocs" method="post"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type="hidden" name="markedcopy_url" value="$env{'form.markedcopy_url'}" /> -<input type="hidden" name="markedcopy_title" value="$env{'form.markedcopy_title'}" /> -<input type="hidden" name="setparms" value="$orderidx" /> -<td><table border='0' cellspacing='2' cellpadding='0'> -<tr><td bgcolor="#DDDDDD"> -<a href='/adm/coursedocs?cmd=up_$index&folderpath=$folderpath$cpinfo'> -<img src="${iconpath}move_up.gif" alt='$lt{'up'}' border='0' /></a></td></tr> -<tr><td bgcolor="#DDDDDD"> -<a href='/adm/coursedocs?cmd=down_$index&folderpath=$folderpath$cpinfo'> -<img src="${iconpath}move_down.gif" alt='$lt{'dw'}' border='0' /></a></td></tr> -</table></td> -<td>$selectbox -</td><td bgcolor="#DDDDDD"> -<a href='javascript:removeres("$folderpath","$index","$renametitle","sequence");'> -<font size="-2" color="#990000">$lt{'rm'}</font></a> -<a href='javascript:cutres("$folderpath","$index","$renametitle","sequence");'> -<font size="-2" color="#550044">$lt{'ct'}</font></a> -<a href='javascript:changename("$folderpath","$index","$renametitle","sequence");'> -<font size="-2" color="#009900">$lt{'rn'}</font></a> + $form_end = '</form>'; + $line.=(<<END); +<td> +<div class="LC_docs_entry_move"> + <a href='/adm/coursedocs?cmd=up_$index&${type}path=$esc_path&${type}symb=$symb$cpinfo'> + <img src="${iconpath}move_up.gif" alt='$lt{'up'}' class="LC_icon" /> + </a> +</div> +<div class="LC_docs_entry_move"> + <a href='/adm/coursedocs?cmd=down_$index&${type}path=$esc_path&${type}symb=$symb$cpinfo'> + <img src="${iconpath}move_down.gif" alt='$lt{'dw'}' class="LC_icon" /> + </a> +</div> +</td> +<td> + $form_start + $form_common + $selectbox + $form_end +</td> +<td class="LC_docs_entry_commands"> + <a href='javascript:removeres("$esc_path","$index","$renametitle","$container","$symb",$skip_confirm);' class="LC_docs_remove">$lt{'rm'}</a> +$cutlink + <a href='javascript:changename("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_rename">$lt{'rn'}</a> $copylink +</td> END - } + } # Figure out what kind of a resource this is my ($extension)=($url=~/\.(\w+)$/); @@ -1548,23 +1975,31 @@ END my $pagearg; my $pagefile; if ($uploaded) { - if ($extension eq 'sequence') { - $icon=$iconpath.'/folder_closed.gif'; - $url=~/$coursenum\/([\/\w]+)\.sequence$/; - $url='/adm/coursedocs?'; - $folderarg=$1; - $isfolder=1; - } elsif ($extension eq 'page') { - $icon=$iconpath.'/page.gif'; - $url=~/$coursenum\/([\/\w]+)\.page$/; - $pagearg=$1; - $url='/adm/coursedocs?'; - $ispage=1; + if (($extension eq 'sequence') || ($extension eq 'page')) { + $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/; + my $containerarg = $1; + if ($extension eq 'sequence') { + $icon=$iconpath.'navmap.folder.closed.gif'; + $folderarg=$containerarg; + $isfolder=1; + } else { + $icon=$iconpath.'page.gif'; + $pagearg=$containerarg; + $ispage=1; + } + if ($allowed) { + $url='/adm/coursedocs?'; + } else { + $url='/adm/supplemental?'; + } } else { &Apache::lonnet::allowuploaded('/adm/coursedoc',$url); } } - $url=~s-^http(\&colon\;|:)//-/adm/wrapper/ext/-; + + my $orig_url = $url; + $orig_url=~s{http(:|:)//https(:|:)//}{https$2//}; + my $external = ($url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}); if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) { my $symb=&Apache::lonnet::symbclean( &Apache::lonnet::declutter('uploaded/'. @@ -1585,31 +2020,59 @@ END } elsif ($url!~/\.(sequence|page)$/) { $url='/adm/coursedocs/showdoc'.$url; } - } elsif ($url=~m|^/ext/|) { + } elsif ($url=~m|^/ext/|) { $url='/adm/wrapper'.$url; + $external = 1; } - $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); + if (&Apache::lonnet::symbverify($symb,$url)) { + $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); + } else { + $url=''; + } if ($container eq 'page') { my $symb=$env{'form.pagesymb'}; - + $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]); $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); } } - my $parameterset=' '; + my ($rand_pick_text,$rand_order_text); if ($isfolder || $extension eq 'sequence') { my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; if ($folderpath) { $folderpath.='&' }; - $folderpath.=$folderarg.'&'.$foldername; +# Append randompick number, hidden, and encrypted with ":" to foldername, +# so it gets transferred between levels + $folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx, + 'parameter_randompick'))[0] + .':'.((&LONCAPA::map::getparameter($orderidx, + 'parameter_hiddenresource'))[0]=~/^yes$/i) + .':'.((&LONCAPA::map::getparameter($orderidx, + 'parameter_encrypturl'))[0]=~/^yes$/i) + .':'.((&LONCAPA::map::getparameter($orderidx, + 'parameter_randomorder'))[0]=~/^yes$/i); $url.='folderpath='.&escape($folderpath).$cpinfo; - $parameterset='<label>'.&mt('Randomly Pick: '). - '<input type="text" size="4" onChange="this.form.submit()" name="randpick_'.$orderidx.'" value="'. - (&Apache::lonratedt::getparameter($orderidx, - 'parameter_randompick'))[0]. - '" />'. -'<font size="-2"><a href="javascript:void(0)">'.&mt('Store').'</a></font></label>'; - + my $rpicknum = (&LONCAPA::map::getparameter($orderidx, + 'parameter_randompick'))[0]; + my $rpckchk; + if ($rpicknum) { + $rpckchk = ' checked="checked"'; + } + my $formname = 'edit_rpick_'.$orderidx; + $rand_pick_text = +'<form action="/adm/coursedocs" method="post" name="'.$formname.'">'."\n". +$form_common."\n". +'<span class="LC_nobreak"><label><input type="checkbox" name="randpickon_'.$orderidx.'" id="rpick_'.$orderidx.'" onclick="'."updatePick(this.form,'$orderidx','check');".'"'.$rpckchk.' /> '.&mt('Randomly Pick').'</label><input type="hidden" name="randompick_'.$orderidx.'" id="rpicknum_'.$orderidx.'" value="'.$rpicknum.'" />'; + if ($rpicknum ne '') { + $rand_pick_text .= ': <a href="javascript:updatePick('."document.$formname,'$orderidx','link'".')">'.$rpicknum.'</a>'; + } + $rand_pick_text .= '</span></form>'; + my $ro_set= + ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':''); + $rand_order_text = +$form_start. +$form_common.' +<span class="LC_nobreak"><label><input type="checkbox" name="randomorder_'.$orderidx.'" onclick="'."this.form.changeparms.value='randomorder';this.form.submit()".'" '.$ro_set.' /> '.&mt('Random Order').' </label></span></form>'; } if ($ispage) { my $pagename=&escape($pagetitle); @@ -1627,32 +2090,76 @@ END $path.$pagearg.'.page'); } $url.='pagepath='.&escape($pagepath). - '&pagesymb='.&escape($symb).$cpinfo; + '&pagesymb='.&escape($symb).$cpinfo; + } + if (($external) && ($allowed)) { + my $form = ($folder =~ /^default/)? 'newext' : 'supnewext'; + $external = ' <a class="LC_docs_ext_edit" href="javascript:edittext(\''.$form.'\',\''.$residx.'\',\''.&escape($title).'\',\''.&escape($orig_url).'\');" >'.&mt('Edit').'</a>'; + } else { + undef($external); + } + my $reinit; + if ($crstype eq 'Community') { + $reinit = &mt('(re-initialize community to access)'); + } else { + $reinit = &mt('(re-initialize course to access)'); + } + $line.='<td>'; + if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { + $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>'; + } elsif ($url) { + $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', + '<img src="'.$icon.'" alt="" class="LC_icon" />',600,500); + } else { + $line.='<img src="'.$icon.'" alt="" class="LC_icon" />'; + } + $line.='</td><td>'; + if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { + $line.='<a href="'.$url.'">'.$title.'</a>'; + } elsif ($url) { + $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&':'?').'inhibitmenu=yes', + $title,600,500); + } else { + $line.=$title.' <span class="LC_docs_reinit_warn">'.$reinit.'</span>'; } - $line.='<td bgcolor="#FFFFBB"><a href="'.$url.'"><img src="'.$icon. - '" border="0"></a></td>'. - "<td bgcolor='#FFFFBB'><a href=\"$url\">$title</a></td>"; + $line.=$external."</td>"; + $rand_pick_text = ' ' if ($rand_pick_text eq ''); + $rand_order_text = ' ' if ($rand_order_text eq ''); if (($allowed) && ($folder!~/^supplemental/)) { my %lt=&Apache::lonlocal::texthash( 'hd' => 'Hidden', 'ec' => 'URL hidden'); my $enctext= - ((&Apache::lonratedt::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':''); + ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':''); my $hidtext= - ((&Apache::lonratedt::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':''); + ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':''); $line.=(<<ENDPARMS); -<td bgcolor="#BBBBFF"><font size='-2'> -<nobr><label><input type="checkbox" name="hidprs_$orderidx" onClick="this.form.submit()" $hidtext /> $lt{'hd'}</label></nobr></td> -<td bgcolor="#BBBBFF"><font size='-2'> -<nobr><label><input type="checkbox" name="encprs_$orderidx" onClick="this.form.submit()" $enctext /> $lt{'ec'}</label></nobr></td> -<td bgcolor="#BBBBFF"><font size="-2">$parameterset</font></td> + <td class="LC_docs_entry_parameter"> + $form_start + $form_common + <label><input type="checkbox" name="hiddenresource_$orderidx" onclick="this.form.changeparms.value='hiddenresource';this.form.submit()" $hidtext /> $lt{'hd'}</label> + $form_end + <br /> + $form_start + $form_common + <label><input type="checkbox" name="encrypturl_$orderidx" onclick="this.form.changeparms.value='encrypturl';this.form.submit()" $enctext /> $lt{'ec'}</label> + $form_end + </td> + <td class="LC_docs_entry_parameter">$rand_pick_text<br /> + $rand_order_text</td> ENDPARMS } - $line.="</form></tr>"; + $line.=&Apache::loncommon::end_data_table_row(); return $line; } -# ---------------------------------------------------------------- tie the hash +=pod + +=item tiehash() + +tie the hash + +=cut sub tiehash { my ($mode)=@_; @@ -1669,7 +2176,7 @@ sub tiehash { $hashtied=1; } } - } + } } sub untiehash { @@ -1678,7 +2185,8 @@ sub untiehash { return OK; } -# --------------------------------------------------------------- check on this + + sub checkonthis { my ($r,$url,$level,$title)=@_; @@ -1687,6 +2195,9 @@ sub checkonthis { $r->rflush(); if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) { $r->print("\n<br />"); + if ($level==0) { + $r->print("<br />"); + } for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } @@ -1696,7 +2207,7 @@ sub checkonthis { my $result=&Apache::lonnet::repcopy( &Apache::lonnet::filelocation('',$url)); if ($result eq 'ok') { - $r->print('<font color="green">'.&mt('ok').'</font>'); + $r->print('<span class="LC_success">'.&mt('ok').'</span>'); $r->rflush(); &Apache::lonnet::countacc($url); $url=~/\.(\w+)$/; @@ -1706,7 +2217,7 @@ sub checkonthis { for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } - $r->print('- '.&mt('Rendering').': '); + $r->print('- '.&mt('Rendering:').' '); my ($errorcount,$warningcount)=split(/:/, &Apache::lonnet::ssi_body($url, ('grade_target'=>'web', @@ -1714,94 +2225,118 @@ sub checkonthis { if (($errorcount) || ($warningcount)) { if ($errorcount) { - $r->print('<img src="/adm/lonMisc/bomb.gif" /><font color="red"><b>'. - $errorcount.' '. - &mt('error(s)').'</b></font> '); + $r->print('<img src="/adm/lonMisc/bomb.gif" alt="'.&mt('bomb').'" /><span class="LC_error">'. + &mt('[quant,_1,error]',$errorcount).'</span>'); } if ($warningcount) { - $r->print('<font color="blue">'. - $warningcount.' '. - &mt('warning(s)').'</font>'); + $r->print('<span class="LC_warning">'. + &mt('[quant,_1,warning]',$warningcount).'</span>'); } } else { - $r->print('<font color="green">'.&mt('ok').'</font>'); + $r->print('<span class="LC_success">'.&mt('ok').'</span>'); } $r->rflush(); } my $dependencies= &Apache::lonnet::metadata($url,'dependencies'); - foreach (split(/\,/,$dependencies)) { - if (($_=~/^\/res\//) && (!$alreadyseen{$_})) { - &checkonthis($r,$_,$level+1); + foreach my $dep (split(/\,/,$dependencies)) { + if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) { + &checkonthis($r,$dep,$level+1); } } } elsif ($result eq 'unavailable') { - $r->print('<font color="red"><b>'.&mt('connection down').'</b></font>'); + $r->print('<span class="LC_error">'.&mt('connection down').'</span>'); } elsif ($result eq 'not_found') { unless ($url=~/\$/) { - $r->print('<font color="red"><b>'.&mt('not found').'</b></font>'); + $r->print('<span class="LC_error">'.&mt('not found').'</b></span>'); } else { - $r->print('<font color="yellow"><b>'.&mt('unable to verify variable URL').'</b></font>'); + $r->print('<span class="LC_error">'.&mt('unable to verify variable URL').'</span>'); } } else { - $r->print('<font color="red"><b>'.&mt('access denied').'</b></font>'); + $r->print('<span class="LC_error">'.&mt('access denied').'</span>'); } - } - } + } + } } -# -# ----------------------------------------------------------------- List Symbs -# + +=pod + +=item list_symbs() + +List Content Identifiers + +=cut + sub list_symbs { my ($r) = @_; - $r->print(&Apache::loncommon::start_page('Symb List')); + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('List of Content Identifiers')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Identifiers')); + $r->print(&startContentScreen('tools')); my $navmap = Apache::lonnavmaps::navmap->new(); - $r->print("<pre>\n"); - foreach my $res ($navmap->retrieveResources()) { - $r->print($res->compTitle()."\t".$res->symb()."\n"); + if (!defined($navmap)) { + $r->print('<h2>'.&mt('Retrieval of List Failed').'</h2>'. + '<div class="LC_error">'. + &mt('Unable to retrieve information about course contents'). + '</div>'); + &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); + } else { + $r->print('<h4 class="LC_info">'.&mt("$crstype Content Identifiers").'</h4>'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Title').'</th><th>'.&mt('Identifier').'</th>'. + &Apache::loncommon::end_data_table_header_row()."\n"); + my $count; + foreach my $res ($navmap->retrieveResources()) { + $r->print(&Apache::loncommon::start_data_table_row(). + '<td>'.$res->compTitle().'</td>'. + '<td>'.$res->symb().'</td>'. + &Apache::loncommon::start_data_table_row()); + $count ++; + } + if (!$count) { + $r->print(&Apache::loncommon::start_data_table_row(). + '<td colspan="2">'.&mt("$crstype is empty").'</td>'. + &Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table()); } - $r->print("\n</pre>\n"); - $r->print('<a href="/adm/coursedocs">'.&mt('Return to DOCS').'</a>'); } -# -# -------------------------------------------------------------- Verify Content -# sub verifycontent { my ($r) = @_; - my $type = &Apache::loncommon::course_type(); - my $loaderror=&Apache::lonnet::overloaderror($r); - if ($loaderror) { return $loaderror; } - $r->print(&Apache::loncommon::start_page('Verify '.$type.' Documents')); + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents')); + $r->print(&startContentScreen('tools')); + $r->print('<h4 class="LC_info">'.&mt($crstype.' content verification').'</h4>'); $hashtied=0; undef %alreadyseen; %alreadyseen=(); &tiehash(); - foreach (keys %hash) { - if ($hash{$_}=~/\.(page|sequence)$/) { - if (($_=~/^src_/) && ($alreadyseen{&unescape($hash{$_})})) { - $r->print('<hr /><font color="red">'. - &mt('The following sequence or page is included more than once in your '.$type.': '). - &unescape($hash{$_}).'</font><br />'. - &mt('Note that grading records for problems included in this sequence or folder will overlap.<hr />')); + + foreach my $key (keys(%hash)) { + if ($hash{$key}=~/\.(page|sequence)$/) { + if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) { + $r->print('<hr /><span class="LC_error">'. + &mt('The following sequence or page is included more than once in your '.$crstype.':').' '. + &unescape($hash{$key}).'</span><br />'. + &mt('Note that grading records for problems included in this sequence or folder will overlap.').'<hr />'); } } - if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$_})})) { - &checkonthis($r,$hash{$_},0,$hash{'title_'.$1}); + if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) { + &checkonthis($r,$hash{$key},0,$hash{'title_'.$1}); } } &untiehash(); - $r->print('<h1>'.&mt('Done').'.</h1>'.'<a href="/adm/coursedocs">'. - &mt('Return to DOCS').'</a>'); + $r->print('<p class="LC_success">'.&mt('Done').'</p>'); } -# -------------------------------------------------------------- Check Versions - sub devalidateversioncache { my $src=shift; &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'. @@ -1810,8 +2345,11 @@ sub devalidateversioncache { sub checkversions { my ($r) = @_; - my $type = &Apache::loncommon::course_type(); - $r->print(&Apache::loncommon::start_page("Check $type Document Versions")); + my $crstype = &Apache::loncommon::course_type(); + $r->print(&Apache::loncommon::start_page("Check $crstype Document Versions")); + $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Document Versions")); + $r->print(&startContentScreen('tools')); + my $header=''; my $startsel=''; my $monthsel=''; @@ -1830,16 +2368,16 @@ sub checkversions { my %newsetversions=(); if ($env{'form.setmostrecent'}) { $haschanged=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { $newsetversions{$1}='mostrecent'; &devalidateversioncache($1); } } } elsif ($env{'form.setcurrent'}) { $haschanged=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { my $getvers=&Apache::lonnet::getversion($1); if ($getvers>0) { $newsetversions{$1}=$getvers; @@ -1849,11 +2387,11 @@ sub checkversions { } } elsif ($env{'form.setversions'}) { $haschanged=1; - foreach (keys %env) { - if ($_=~/^form\.set_version_(.+)$/) { + foreach my $key (keys(%env)) { + if ($key=~/^form\.set_version_(.+)$/) { my $src=$1; - if (($env{$_}) && ($env{$_} ne $setversions{$src})) { - $newsetversions{$src}=$env{$_}; + if (($env{$key}) && ($env{$key} ne $setversions{$src})) { + $newsetversions{$src}=$env{$key}; &devalidateversioncache($src); } } @@ -1862,20 +2400,22 @@ sub checkversions { if ($haschanged) { if (&Apache::lonnet::put('resourceversions',\%newsetversions, $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { - $r->print('<h1>'.&mt('Your Version Settings have been Stored').'</h1>'); + $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { + $r->print(&Apache::loncommon::confirmwrapper( + &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved')))); } else { - $r->print('<h1><font color="red">'.&mt('An Error Occured while Attempting to Store your Version Settings').'</font></h1>'); + $r->print(&Apache::loncommon::confirmwrapper( + &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1))); } &mark_hash_old(); } &changewarning($r,''); if ($env{'form.timerange'} eq 'all') { # show all documents - $header=&mt('All Documents in '.$type); + $header=&mt('All Documents in '.$crstype); $allsel=1; - foreach (keys %hash) { - if ($_=~/^ids\_(\/res\/.+)$/) { + foreach my $key (keys(%hash)) { + if ($key=~/^ids\_(\/res\/.+)$/) { my $src=$1; $changes{$src}=1; } @@ -1885,7 +2425,7 @@ sub checkversions { %changes=&Apache::lonnet::dump ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); - my $firstkey=(keys %changes)[0]; + my $firstkey=(keys(%changes))[0]; unless ($firstkey=~/^error\:/) { unless ($env{'form.timerange'}) { $env{'form.timerange'}=604800; @@ -1917,26 +2457,32 @@ sub checkversions { $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}); my %lt=&Apache::lonlocal::texthash - ('st' => 'Version changes since start of '.$type, + ('st' => 'Version changes since start of '.$crstype, 'lm' => 'Version changes since last Month', 'lw' => 'Version changes since last Week', 'sy' => 'Version changes since Yesterday', 'al' => 'All Resources (possibly large output)', + 'cd' => 'Change display', 'sd' => 'Display', 'fi' => 'File', 'md' => 'Modification Date', 'mr' => 'Most recently published Version', - 've' => 'Version used in '.$type, - 'vu' => 'Set Version to be used in '.$type, -'sv' => 'Set Versions to be used in '.$type.' according to Selections below', + 've' => 'Version used in '.$crstype, + 'vu' => 'Set Version to be used in '.$crstype, +'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below', 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)', 'sc' => 'Set all Resource Versions to current Version (Fix Versions)', - 'di' => 'Differences'); + 'di' => 'Differences', + 'save' => 'Save changes', + 'vers' => 'Version choice(s) for specific resources', + 'act' => 'Actions'); $r->print(<<ENDHEADERS); +<h4 class="LC_info">$header</h4> <form action="/adm/coursedocs" method="post"> <input type="hidden" name="versions" value="1" /> -<input type="submit" name="setmostrecent" value="$lt{'sm'}" /> -<input type="submit" name="setcurrent" value="$lt{'sc'}" /><hr /> +<div class="LC_left_float"> +<fieldset> +<legend>$lt{'cd'}</legend> <select name="timerange"> <option value='all' $allsel>$lt{'al'}</option> <option value="-1" $startsel>$lt{'st'}</option> @@ -1945,56 +2491,68 @@ sub checkversions { <option value="86400" $daysel>$lt{'sy'}</option> </select> <input type="submit" name="display" value="$lt{'sd'}" /> -<h3>$header</h3> -<input type="submit" name="setversions" value="$lt{'sv'}" /> +</fieldset> +</div> +<div class="LC_left_float"> +<fieldset> +<legend>$lt{'act'}</legend> +$lt{'sm'}: <input type="submit" name="setmostrecent" value="Go" /><br /> +$lt{'sc'}: <input type="submit" name="setcurrent" value="Go" /> +</fieldset> +</div> +<br clear="all" /> +<hr /> +<h4>$lt{'vers'}</h4> +<input type="submit" name="setversions" value="$lt{'save'}" /> <table border="0"> ENDHEADERS - foreach (sort keys %changes) { - if ($changes{$_}>$starttime) { - my ($root,$extension)=($_=~/^(.*)\.(\w+)$/); - my $currentversion=&Apache::lonnet::getversion($_); + #number of columns for version history + my $num_ver_col = 1; + $r->print( + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '<th>'.&mt('Resources').'</th>'. + "<th>$lt{'mr'}</th>". + "<th>$lt{'ve'}</th>". + "<th>$lt{'vu'}</th>". + '<th colspan="'.$num_ver_col.'">'.&mt('History').'</th>'. + '</b>'); + foreach my $key (sort(keys(%changes))) { + if ($changes{$key}>$starttime) { + my ($root,$extension)=($key=~/^(.*)\.(\w+)$/); + my $currentversion=&Apache::lonnet::getversion($key); if ($currentversion<0) { - $currentversion=&mt('Could not be determined.'); + $currentversion='<span class="LC_error">'.&mt('Could not be determined.').'</span>'; } - my $linkurl=&Apache::lonnet::clutter($_); - $r->print( - '<tr><td colspan="5"><br /><br /><font size="+1"><b>'. - &Apache::lonnet::gettitle($linkurl). - '</b></font></td></tr>'. - '<tr><td> </td>'. - '<td colspan="4">'. - '<a href="'.$linkurl.'" target="cat">'.$linkurl. - '</a></td></tr>'. - '<tr><td></td>'. - '<td title="'.$lt{'md'}.'">'. - &Apache::lonlocal::locallocaltime( - &Apache::lonnet::metadata($root.'.'.$extension, - 'lastrevisiondate') - ). - '</td>'. - '<td title="'.$lt{'mr'}.'"><nobr>Most Recent: '. - '<font size="+1">'.$currentversion.'</font>'. - '</nobr></td>'. - '<td title="'.$lt{'ve'}.'"><nobr>In '.$type.': '. - '<font size="+1">'); + my $linkurl=&Apache::lonnet::clutter($key); + $r->print( + &Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row(). + '<td><b>'.&Apache::lonnet::gettitle($linkurl).'</b><br>'. + '<a href="'.$linkurl.'" target="cat">'.$linkurl.'</a></td>'. + '<td align="right">'.$currentversion.'<span class="LC_fontsize_medium"><br>('. + &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).')</span></td>'. + '<td align="right">'); # Used in course my $usedversion=$hash{'version_'.$linkurl}; if (($usedversion) && ($usedversion ne 'mostrecent')) { - $r->print($usedversion); + if($usedversion != $currentversion){ + $r->print('<span class="LC_warning">'.$usedversion.'</span>'); + }else{ + $r->print($usedversion); + } } else { $r->print($currentversion); } - $r->print('</font></nobr></td><td title="'.$lt{'vu'}.'">'. - '<nobr>Use: '); + $r->print('</td><td title="'.$lt{'vu'}.'">'); # Set version $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, 'set_version_'.$linkurl, - ('select_form_order' => + {'select_form_order' => ['',1..$currentversion,'mostrecent'], '' => '', - 'mostrecent' => 'most recent', - map {$_,$_} (1..$currentversion)))); - $r->print('</nobr></td></tr><tr><td></td>'); + 'mostrecent' => &mt('most recent'), + map {$_,$_} (1..$currentversion)})); my $lastold=1; for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { my $url=$root.'.'.$prevvers.'.'.$extension; @@ -2003,22 +2561,22 @@ ENDHEADERS $lastold=$prevvers; } } - # + # # Code to figure out how many version entries should go in # each of the four columns my $entries_per_col = 0; my $num_entries = ($currentversion-$lastold); - if ($num_entries % 4 == 0) { - $entries_per_col = $num_entries/4; + if ($num_entries % $num_ver_col == 0) { + $entries_per_col = $num_entries/$num_ver_col; } else { - $entries_per_col = $num_entries/4 + 1; + $entries_per_col = $num_entries/$num_ver_col + 1; } my $entries_count = 0; - $r->print('<td valign="top"><font size="-2">'); + $r->print('<td valign="top"><span class="LC_fontsize_medium">'); my $cols_output = 1; for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { my $url=$root.'.'.$prevvers.'.'.$extension; - $r->print('<nobr><a href="'.&Apache::lonnet::clutter($url). + $r->print('<span class="LC_nobreak"><a href="'.&Apache::lonnet::clutter($url). '">'.&mt('Version').' '.$prevvers.'</a> ('. &Apache::lonlocal::locallocaltime( &Apache::lonnet::metadata($url, @@ -2029,25 +2587,25 @@ ENDHEADERS $r->print(' <a href="/adm/diff?filename='. &Apache::lonnet::clutter($root.'.'.$extension). '&versionone='.$prevvers. - '">'.&mt('Diffs').'</a>'); + '" target="diffs">'.&mt('Diffs').'</a>'); } - $r->print('</nobr><br />'); + $r->print('</span><br />'); if (++$entries_count % $entries_per_col == 0) { - $r->print('</font></td>'); - if ($cols_output != 4) { - $r->print('<td valign="top"><font size="-2">'); + $r->print('</span></td>'); + if ($cols_output != $num_ver_col) { + $r->print('<td valign="top"><span class="LC_fontsize_medium">'); $cols_output++; } } } - while($cols_output++ < 4) { - $r->print('</font></td><td><font>') + while($cols_output++ < $num_ver_col) { + $r->print('</span></td><td>'); } - $r->print('</font></td></tr>'."\n"); } } - $r->print('</table></form>'); - $r->print('<h1>'.&mt('Done').'.</h1>'); + $r->print('</td>'.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(). + '<input type="submit" name="setversions" value="'.$lt{'save'}.'" />'); &untiehash(); } @@ -2093,32 +2651,114 @@ sub changewarning { $message='Changes will become active for your current session after [_1], or the next time you log in.'; } $r->print("\n\n". -'<script>function reinit(tf) { tf.submit();'.$postexec.' }</script>'."\n". +'<script type="text/javascript">'."\n". +'// <![CDATA['."\n". +'function reinit(tf) { tf.submit();'.$postexec.' }'."\n". +'// ]]>'."\n". +'</script>'."\n". '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'. '<input type="hidden" name="orgurl" value="'.$url. -'" /><input type="hidden" name="selectrole" value="1" /><h3><font color="red">'. +'" /><input type="hidden" name="selectrole" value="1" /><p class="LC_warning">'. &mt($message,' <input type="hidden" name="'. $env{'request.role'}.'" value="1" /><input type="button" value="'. - &mt('re-initializing '.$course_type).'" onClick="reinit(this.form)" />'). -$help{'Caching'}.'</font></h3></form>'."\n\n"); + &mt('re-initializing '.$course_type).'" onclick="reinit(this.form)" />'). +$help{'Caching'}.'</p></form>'."\n\n"); +} + + +sub init_breadcrumbs { + my ($form,$text)=@_; + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1", + text=>&Apache::loncommon::course_type().' Editor', + faq=>273, + bug=>'Instructor Interface', + help => 'Docs_Adding_Course_Doc'}); + &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1', + text=>$text, + faq=>273, + bug=>'Instructor Interface'}); +} + +# subroutine to list form elements +sub create_list_elements { + my @formarr = @_; + my $list = ''; + for my $button (@formarr){ + for my $picture(keys %$button) { + $list .= &Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text'}); + } + } + return $list; +} + +# subroutine to create ul from list elements +sub create_form_ul { + my $list = shift; + my $ul = &Apache::lonhtmlcommon::htmltag('ul',$list, {class => 'LC_ListStyleNormal'}); + return $ul; +} + +# +# Start tabs +# + +sub startContentScreen { + my ($mode) = @_; + my $output = '<ul class="LC_TabContentBigger" id="mainnav">'; + if (($mode eq 'navmaps') || ($mode eq 'supplemental')) { + $output .= '<li'.(($mode eq 'navmaps')?' class="active"':'').'><a href="/adm/navmaps"><b> '.&mt('Content Overview').' </b></a></li>'."\n"; + $output .= '<li'.(($mode eq 'coursesearch')?' class="active"':'').'><a href="/adm/searchcourse"><b> '.&mt('Content Search').' </b></a></li>'."\n"; + $output .= '<li'.(($mode eq 'courseindex')?' class="active"':'').'><a href="/adm/indexcourse"><b> '.&mt('Content Index').' </b></a></li>'."\n"; + $output .= '<li '.(($mode eq 'suppdocs')?' class="active"':'').'><a href="/adm/supplemental"><b>'.&mt('Supplemental Content').'</b></a></li>'; + } else { + $output .= '<li '.(($mode eq 'docs')?' class="active"':'').' id="tabbededitor"><a href="/adm/coursedocs?forcestandard=1"><b> '.&mt('Content Editor').' </b></a></li>'."\n"; + $output .= '<li '.(($mode eq 'suppdocs')?' class="active"':'').'><a href="/adm/coursedocs?forcesupplement=1"><b>'.&mt('Supplemental Content Editor').'</b></a></li>'."\n"; + $output .= '<li '.(($mode eq 'tools')?' class="active"':'').'><a href="/adm/coursedocs?tools=1"><b> '.&mt('Content Utilities').' </b></a></li>'."\n"; + '><a href="/adm/coursedocs?tools=1"><b> '.&mt('Content Utilities').' </b></a></li>'; + } + $output .= "\n".'</ul>'."\n"; + $output .= '<div class="LC_DocsBox" style="clear:both;margin:0;" id="contenteditor">'. + '<div id="maincoursedoc" style="margin:0 0;padding:0 0;">'. + '<div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">'; + return $output; +} + +# +# End tabs +# + +sub endContentScreen { + return '</div></div></div>'; +} + +sub supplemental_base { + return 'supplemental&'.&escape(&mt('Supplemental '.&Apache::loncommon::course_type().' Content')); } -# ================================================================ Main Handler sub handler { my $r = shift; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; - my $type = &Apache::loncommon::course_type(); +# get course data + my $crstype = &Apache::loncommon::course_type(); + my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + +# graphics settings + $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL').'/'); + +# # --------------------------------------------- Initialize help topics for this - foreach ('Adding_Course_Doc','Main_Course_Documents', - 'Adding_External_Resource','Navigate_Content', - 'Adding_Folders','Docs_Overview', 'Load_Map', - 'Supplemental','Score_Upload_Form','Adding_Pages', - 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive', - 'Check_Resource_Versions','Verify_Content') { - $help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_); + foreach my $topic ('Adding_Course_Doc','Main_Course_Documents', + 'Adding_External_Resource','Navigate_Content', + 'Adding_Folders','Docs_Overview', 'Load_Map', + 'Supplemental','Score_Upload_Form','Adding_Pages', + 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive', + 'Check_Resource_Versions','Verify_Content') { + $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic); } # Composite help files $help{'Syllabus'} = &Apache::loncommon::help_open_topic( @@ -2129,281 +2769,520 @@ sub handler { 'Option_Response_Simple'); $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic( 'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages'); - $help{'My Personal Info'} = &Apache::loncommon::help_open_topic( + $help{'My Personal Information Page'} = &Apache::loncommon::help_open_topic( 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages'); + $help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files'); $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching'); -# does this user have privileges to modify docs - my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'}); + + my $allowed; +# URI is /adm/supplemental when viewing supplemental docs in non-edit mode. + unless ($r->uri eq '/adm/supplemental') { + # does this user have privileges to modify content. + $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'}); + } - if ($allowed && $env{'form.verify'}) { + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['chooseserver', + 'inhibitmenu']); + if ($allowed && $env{'form.chooseserver'}) { + &choose_dump_server($r); + return OK; + } elsif ($allowed && $env{'form.verify'}) { + &init_breadcrumbs('verify','Verify Content'); &verifycontent($r); } elsif ($allowed && $env{'form.listsymbs'}) { + &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); + } elsif ($allowed && $env{'form.docslog'}) { + &init_breadcrumbs('docslog','Show Log'); + my $folder = $env{'form.folder'}; + if ($folder eq '') { + $folder='default'; + } + &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath); } elsif ($allowed && $env{'form.versions'}) { + &init_breadcrumbs('versions','Check/Set Resource Versions'); &checkversions($r); } elsif ($allowed && $env{'form.dumpcourse'}) { + &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' Content to Authoring Space'); &dumpcourse($r); } elsif ($allowed && $env{'form.exportcourse'}) { - &exportcourse($r); + &init_breadcrumbs('exportcourse','IMS Export'); + &Apache::imsexport::exportcourse($r); } else { -# is this a standard course? +# +# Done catching special calls +# The whole rest is for course and supplemental documents and utilities menu +# Get the parameters that may be needed +# + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['folderpath','pagepath', + 'pagesymb','forcesupplement','forcestandard', + 'tools','symb','command']); + +# 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 my $standard=($env{'request.course.uri'}=~/^\/uploaded\//); - my $forcestandard = 0; - my $forcesupplement; + +# Decide whether this should display supplemental or main content or utilities +# supplementalflag=1: show supplemental documents +# supplementalflag=0: show standard documents +# toolsflag=1: show utilities + + + my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) { + $supplementalflag=0; + } + if ($env{'form.forcesupplement'}) { $supplementalflag=1; } + if ($env{'form.forcestandard'}) { $supplementalflag=0; } + unless ($allowed) { $supplementalflag=1; } + unless ($standard) { $supplementalflag=1; } + my $toolsflag=0; + if ($env{'form.tools'}) { $toolsflag=1; } + my $script=''; my $showdoc=0; + my $addentries = {}; + my $container; my $containertag; my $uploadtag; - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath','pagepath', - 'pagesymb','markedcopy_url', - 'markedcopy_title']); - if ($env{'form.folderpath'}) { - my (@folderpath)=split('&',$env{'form.folderpath'}); - $env{'form.foldername'}=&unescape(pop(@folderpath)); - $env{'form.folder'}=pop(@folderpath); - } - if ($env{'form.pagepath'}) { - my (@pagepath)=split('&',$env{'form.pagepath'}); - $env{'form.pagename'}=&unescape(pop(@pagepath)); - $env{'form.folder'}=pop(@pagepath); - $containertag = '<input type="hidden" name="pagepath" value="" />'. - '<input type="hidden" name="pagesymb" value="" />'; - $uploadtag = '<input type="hidden" name="pagepath" value="'.$env{'form.pagepath'}.'" />'. - '<input type="hidden" name="pagesymb" value="'.$env{'form.pagesymb'}.'" />'; - } - if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { - $showdoc='/'.$1; - } - unless ($showdoc) { # got called from remote - if (($env{'form.folder'}=~/^(?:group|default)_/) || - ($env{'form.folder'} =~ m:^\d+/(pages|sequences)/:)) { - $forcestandard = 1; - } - $forcesupplement=($env{'form.folder'}=~/^supplemental_/); - - if ($allowed) { - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']); - $script=&Apache::lonratedt::editscript('simple'); + +# Do we directly jump somewhere? + + if ($env{'form.command'} eq 'direct') { + my ($mapurl,$id,$resurl); + if ($env{'form.symb'} ne '') { + ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'}); + if ($resurl=~/\.(sequence|page)$/) { + $mapurl=$resurl; + } elsif ($resurl eq 'adm/navmaps') { + $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; + } + my $mapresobj; + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + $mapresobj = $navmap->getResourceByUrl($mapurl); + } + $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; + my $type=$2; + my $path; + if (ref($mapresobj)) { + my $pcslist = $mapresobj->map_hierarchy(); + if ($pcslist ne '') { + foreach my $pc (split(/,/,$pcslist)) { + next if ($pc <= 1); + my $res = $navmap->getByMapPc($pc); + if (ref($res)) { + my $thisurl = $res->src(); + $thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; + my $thistitle = $res->title(); + $path .= '&'. + &Apache::lonhtmlcommon::entity_encode($thisurl).'&'. + &Apache::lonhtmlcommon::entity_encode($thistitle). + ':'.$res->randompick(). + ':'.$res->randomout(). + ':'.$res->encrypted(). + ':'.$res->randomorder(); + } + } + } + $path .= '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. + &Apache::lonhtmlcommon::entity_encode($mapresobj->title()). + ':'.$mapresobj->randompick(). + ':'.$mapresobj->randomout(). + ':'.$mapresobj->encrypted(). + ':'.$mapresobj->randomorder(); + } else { + my $maptitle = &Apache::lonnet::gettitle($mapurl); + $path = '&default&...::::'. + '&'.&Apache::lonhtmlcommon::entity_encode($mapurl).'&'. + &Apache::lonhtmlcommon::entity_encode($maptitle).'::::'; + } + $path = 'default&'. + &Apache::lonhtmlcommon::entity_encode('Main Course Documents'). + $path; + if ($type eq 'sequence') { + $env{'form.folderpath'}=$path; + $env{'form.pagepath'}=''; + } else { + $env{'form.pagepath'}=$path; + $env{'form.folderpath'}=''; + } + } elsif ($env{'form.supppath'} ne '') { + $env{'form.folderpath'}=$env{'form.supppath'}; + } + } elsif ($env{'form.command'} eq 'editdocs') { + $env{'form.folderpath'} = 'default&'. + &Apache::lonhtmlcommon::entity_encode('Main Course Content'); + $env{'form.pagepath'}=''; + } elsif ($env{'form.command'} eq 'editsupp') { + $env{'form.folderpath'} = 'default&'. + &Apache::lonhtmlcommon::entity_encode('Supplemental Content'); + $env{'form.pagepath'}=''; + } + +# Where do we store these for when we come back? + my $stored_folderpath='docs_folderpath'; + if ($supplementalflag) { + $stored_folderpath='docs_sup_folderpath'; + } + +# No folderpath, no pagepath, see if we have something stored + if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) { + &Apache::loncommon::restore_course_settings($stored_folderpath, + {'folderpath' => 'scalar'}); + } + +# If we are not allowed to make changes, all we can see are supplemental docs + if (!$allowed) { + $env{'form.pagepath'}=''; + unless ($env{'form.folderpath'} =~ /^supplemental/) { + $env{'form.folderpath'} = &supplemental_base(); + } + } +# If we still not have a folderpath, see if we can resurrect at pagepath + if (!$env{'form.folderpath'} && $allowed) { + &Apache::loncommon::restore_course_settings($stored_folderpath, + {'pagepath' => 'scalar'}); + } +# Make the zeroth entry in supplemental docs page paths, so we can get to top level + if ($env{'form.folderpath'} =~ /^supplemental_\d+/) { + $env{'form.folderpath'} = &supplemental_base() + .'&'. + $env{'form.folderpath'}; + } +# If after all of this, we still don't have any paths, make them + unless (($env{'form.pagepath'}) || ($env{'form.folderpath'})) { + if ($supplementalflag) { + $env{'form.folderpath'}=&supplemental_base(); + } else { + $env{'form.folderpath'}='default'; } - } else { # got called in sequence from course - $allowed=0; } -# get course data - my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; - my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; +# Store this + unless ($toolsflag) { + &Apache::loncommon::store_course_settings($stored_folderpath, + {'pagepath' => 'scalar', + 'folderpath' => 'scalar'}); + if ($env{'form.folderpath'}) { + my (@folderpath)=split('&',$env{'form.folderpath'}); + $env{'form.foldername'}=&unescape(pop(@folderpath)); + $env{'form.folder'}=pop(@folderpath); + $container='sequence'; + } + if ($env{'form.pagepath'}) { + my (@pagepath)=split('&',$env{'form.pagepath'}); + $env{'form.pagename'}=&unescape(pop(@pagepath)); + $env{'form.folder'}=pop(@pagepath); + $container='page'; + $containertag = '<input type="hidden" name="pagepath" value="" />'. + '<input type="hidden" name="pagesymb" value="" />'; + $uploadtag = + '<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />'. + '<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />'. + '<input type="hidden" name="folderpath" value="" />'; + } else { + my $folderpath=$env{'form.folderpath'}; + if (!$folderpath) { + if ($env{'form.folder'} eq '' || + $env{'form.folder'} eq 'supplemental') { + $folderpath='default&'. + &escape(&mt('Main '.$crstype.' Documents')); + } + } + $containertag = '<input type="hidden" name="folderpath" value="" />'; + $uploadtag = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />'; + } + if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { + $showdoc='/'.$1; + } + if ($showdoc) { # got called in sequence from course + $allowed=0; + } else { + if ($allowed) { + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']); + $script=&Apache::lonratedt::editscript('simple'); + } + } + } -# get personal data +# get personal data my $uname=$env{'user.name'}; my $udom=$env{'user.domain'}; - my $plainname=&escape( - &Apache::loncommon::plainname($uname,$udom)); - -# graphics settings - - $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/"); + my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom)); if ($allowed) { - $script .= &editing_js($udom,$uname); + if ($toolsflag) { + $script .= &inject_data_js(); + my ($home,$other,%outhash)=&authorhosts(); + if (!$home && $other) { + my @hosts; + foreach my $aurole (keys(%outhash)) { + unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) { + push(@hosts,$outhash{$aurole}); + } + } + $script .= &dump_switchserver_js(@hosts); + } + } else { + my @tabids; + if ($supplementalflag) { + @tabids = ('002','ee2','ff2'); + } else { + @tabids = ('aa1','bb1','cc1','ff1'); + unless ($env{'form.pagepath'}) { + unshift(@tabids,'001'); + push(@tabids,('dd1','ee1')); + } + } + my $tabidstr = join("','",@tabids); + $script .= &editing_js($udom,$uname,$supplementalflag). + &history_tab_js(). + &inject_data_js(). + &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr); + $addentries = { + onload => "javascript:resize_scrollbox('contentscroll','1','1');", + }; + } } # -------------------------------------------------------------------- Body tag - $script = '<script type="text/javascript">'."\n".$script."\n".'</script>'; - $r->print(&Apache::loncommon::start_page("$type Documents", $script, - {'force_register' => $showdoc,}). - &Apache::loncommon::help_open_menu('','',273,'RAT')); - + $script = '<script type="text/javascript">'."\n" + .'// <![CDATA['."\n" + .$script."\n" + .'// ]]>'."\n" + .'</script>'."\n"; + + # Breadcrumbs + &Apache::lonhtmlcommon::clear_breadcrumbs(); + unless ($showdoc) { + &Apache::lonhtmlcommon::add_breadcrumb({ + href=>"/adm/coursedocs",text=>"$crstype Contents"}); + + $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, + {'force_register' => $showdoc, + 'add_entries' => $addentries, + }) + .&Apache::loncommon::help_open_menu('','',273,'RAT') + .&Apache::lonhtmlcommon::breadcrumbs( + 'Editing '.$crstype.' Contents', + 'Docs_Adding_Course_Doc') + ); + } else { + $r->print(&Apache::loncommon::start_page("$crstype documents",undef, + {'force_register' => $showdoc,})); + } + my %allfiles = (); my %codebase = (); - my ($upload_result,$upload_output); + my ($upload_result,$upload_output,$uploadphase); if ($allowed) { - if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { -# Process file upload - phase one - upload and parse primary file. - $upload_result = &process_file_upload(\$upload_output,$coursenum, - $coursedom,\%allfiles, - \%codebase,$1); - if ($upload_result eq 'phasetwo') { - $r->print($upload_output); - } - } elsif ($env{'form.phasetwo'}) { - my %newname = (); - my %origname = (); - my %attribs = (); - my $updateflag = 0; - my $residx = $env{'form.newidx'}; - my $primary_url = &unescape($env{'form.primaryurl'}); -# Process file upload - phase two - gather secondary files. - for (my $i=0; $i<$env{'form.phasetwo'}; $i++) { - if ($env{'form.embedded_item_'.$i.'.filename'}) { - my $javacodebase; - $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx); - $origname{$i} = &unescape($env{'form.embedded_orig_'.$i}); - if (exists($env{'form.embedded_codebase_'.$i})) { - $javacodebase = &unescape($env{'form.embedded_codebase_'.$i}); - $origname{$i} =~ s#^\Q$javacodebase\E/##; - } - my @attributes = (); - if ($env{'form.embedded_attrib_'.$i} =~ /:/) { - @attributes = split/:/,$env{'form.embedded_attrib_'.$i}; - } else { - @attributes = ($env{'form.embedded_attrib_'.$i}); - } - foreach (@attributes) { - push(@{$attribs{$i}},&unescape($_)); - } - if ($javacodebase) { - $codebase{$i} = $javacodebase; - $codebase{$i} =~ s#/$##; - $updateflag = 1; - } - } - unless ($newname{$i} eq $origname{$i}) { - $updateflag = 1; - } - } -# Process file upload - phase three - modify primary file - if ($updateflag) { - my ($content,$rtncode); - my $updateflag = 0; - my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode); - if ($getstatus eq 'ok') { - foreach my $item (keys %newname) { - if ($newname{$item} ne $origname{$item}) { - my $attrib_regexp = ''; - if (@{$attribs{$item}} > 1) { - $attrib_regexp = join('|',@{$attribs{$item}}); - } else { - $attrib_regexp = $attribs{$item}[0]; - } - if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) { - } - $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi; - } - if (exists($codebase{$item})) { - $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs - } - } -# Save edited file. - my $saveresult; - my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; - my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; - my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult); - } else { - &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus); - } - } + if (($env{'form.uploaddoc.filename'}) && + ($env{'form.cmd'}=~/^upload_(\w+)/)) { + my $context = $1; + # Process file upload - phase one - upload and parse primary file. + undef($hadchanges); + $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, + \%allfiles,\%codebase,$context); + if ($hadchanges) { + &mark_hash_old(); + } + $r->print($upload_output); + } elsif ($env{'form.phase'} eq 'upload_embedded') { + # Process file upload - phase two - upload embedded objects + $uploadphase = 'check_embedded'; + my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"'); + my $state = &embedded_form_elems($uploadphase,$primaryurl, + $env{'form.newidx'}); + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my ($destination,$dir_root) = &embedded_destination(); + my $url_root = '/uploaded/'.$docudom.'/'.$docuname; + my $actionurl = '/adm/coursedocs'; + my ($result,$flag) = + &Apache::loncommon::upload_embedded('coursedoc',$destination, + $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state, + $actionurl); + $r->print($result.&return_to_editor()); + } elsif ($env{'form.phase'} eq 'check_embedded') { + # Process file upload - phase three - modify references in HTML file + $uploadphase = 'modified_orightml'; + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my ($destination,$dir_root) = &embedded_destination(); + my $result = + &Apache::loncommon::modify_html_refs('coursedoc',$destination, + $docuname,$docudom,undef, + $dir_root); + $r->print($result.&return_to_editor()); + } elsif ($env{'form.phase'} eq 'decompress_uploaded') { + $uploadphase = 'decompress_phase_one'; + $r->print(&decompression_phase_one(). + &return_to_editor()); + } elsif ($env{'form.phase'} eq 'decompress_cleanup') { + $uploadphase = 'decompress_phase_two'; + $r->print(&decompression_phase_two(). + &return_to_editor()); } } - unless ($showdoc || $upload_result eq 'phasetwo') { + if ($allowed && $toolsflag) { + $r->print(&startContentScreen('tools')); + $r->print(&generate_admin_menu($crstype)); + $r->print(&endContentScreen()); + } elsif ((!$showdoc) && (!$uploadphase)) { # ----------------------------------------------------------------------------- my %lt=&Apache::lonlocal::texthash( - 'uplm' => 'Upload a new main '.lc($type).' document', - 'upls' => 'Upload a new supplemental '.lc($type).' document', + 'uplm' => 'Upload a new main '.lc($crstype).' document', + 'upls' => 'Upload a new supplemental '.lc($crstype).' document', 'impp' => 'Import a document', - 'pubd' => 'Published documents', 'copm' => 'All documents out of a published map into this folder', - 'spec' => 'Special documents', - 'upld' => 'Upload Document', + 'upld' => 'Import Document', 'srch' => 'Search', 'impo' => 'Import', - 'book' => 'Import Bookmarks', + 'lnks' => 'Import from Stored Links', 'selm' => 'Select Map', 'load' => 'Load Map', - 'reco' => 'Recover Deleted Resources', + 'reco' => 'Recover Deleted Documents', 'newf' => 'New Folder', 'newp' => 'New Composite Page', 'extr' => 'External Resource', 'syll' => 'Syllabus', - 'navc' => 'Navigate Contents', - 'sipa' => 'Simple Page', + 'navc' => 'Table of Contents', + 'sipa' => 'Simple Course Page', 'sipr' => 'Simple Problem', 'drbx' => 'Drop Box', - 'scuf' => 'Score Upload Form', - 'bull' => 'Bulletin Board', - 'mypi' => 'My Personal Info', - 'abou' => 'About User', - 'imsf' => 'Import IMS package', + 'scuf' => 'External Scores (handgrade, upload, clicker)', + 'bull' => 'Discussion Board', + 'mypi' => 'My Personal Information Page', + 'grpo' => 'Group Portfolio', + 'rost' => 'Course Roster', + 'abou' => 'Personal Information Page for a User', + 'imsf' => 'IMS Import', + 'imsl' => 'Import IMS package', 'file' => 'File', 'title' => 'Title', 'comment' => 'Comment', - 'parse' => 'If HTML file, upload embedded images/multimedia files' + 'parse' => 'Upload embedded images/multimedia files if HTML file', + 'nd' => 'Upload Document', + 'pm' => 'Published Map', + 'sd' => 'Special Document', + 'mo' => 'More Options', ); # ----------------------------------------------------------------------------- + my $fileupload=(<<FIUP); + $lt{'file'}:<br /> + <input type="file" name="uploaddoc" size="40" /> +FIUP + + my $checkbox=(<<CHBO); + <!-- <label>$lt{'parse'}? + <input type="checkbox" name="parserflag" /> + </label> --> + <label> + <input type="checkbox" name="parserflag" checked="checked" /> $lt{'parse'} + </label> +CHBO + + my $fileuploada = "<br clear='all' /><input type='submit' value='".$lt{'upld'}."' /> $help{'Uploading_From_Harddrive'}"; + my $fileuploadform=(<<FUFORM); + <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data"> + <input type="hidden" name="active" value="aa" /> + $fileupload + <br /> + $lt{'title'}:<br /> + <input type="text" size="60" name="comment" /> + $uploadtag + <input type="hidden" name="cmd" value="upload_default" /> + <br /> + <span class="LC_nobreak" style="float:left"> + $checkbox + </span> +FUFORM + $fileuploadform .= $fileuploada.'</form>'; + + my $simpleeditdefaultform=(<<SEDFFORM); + <form action="/adm/coursedocs" method="post" name="simpleeditdefault"> + <input type="hidden" name="active" value="bb" /> +SEDFFORM + my @simpleeditdefaultforma = ( + { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/src.png" alt="'.$lt{srch}.'" onclick="javascript:groupsearch()" />' => "$uploadtag<a class='LC_menubuttons_link' href='javascript:groupsearch()'>$lt{'srch'}</a>" }, + { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/res.png" alt="'.$lt{impo}.'" onclick="javascript:groupimport();"/>' => "<a class='LC_menubuttons_link' href='javascript:groupimport();'>$lt{'impo'}</a>$help{'Importing_LON-CAPA_Resource'}" }, + { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/wishlist.png" alt="'.$lt{lnks}.'" onclick="javascript:open_StoredLinks_Import();" />' => "<a class='LC_menubuttons_link' href='javascript:open_StoredLinks_Import();'>$lt{'lnks'}</a>" }, + ); + $simpleeditdefaultform .= &create_form_ul(&create_list_elements(@simpleeditdefaultforma)); + $simpleeditdefaultform .=(<<SEDFFORM); + <hr id="bb_hrule" style="width:0px;text-align:left;margin-left:0" /> + $lt{'copm'}<br /> + <input type="text" size="40" name="importmap" /><br /> + <span class="LC_nobreak" style="float:left"><input type="button" + onclick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')" + value="$lt{'selm'}" /> <input type="submit" name="loadmap" value="$lt{'load'}" /> + $help{'Load_Map'}</span> + </form> +SEDFFORM + + my $extresourcesform=(<<ERFORM); + <form action="/adm/coursedocs" method="post" name="newext"> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makenewext('newext');">$lt{'extr'}</a>$help{'Adding_External_Resource'} + </form> +ERFORM + + if ($allowed) { - my $dumpbut=&dumpbutton(); - my $exportbut=&exportbutton(); - my %lt=&Apache::lonlocal::texthash( - 'vc' => 'Verify Content', - 'cv' => 'Check/Set Resource Versions', - 'ls' => 'List Symbs', - ); + &update_paste_buffer($coursenum,$coursedom); + $r->print(<<HIDDENFORM); + <form name="renameform" method="post" action="/adm/coursedocs"> + <input type="hidden" name="title" /> + <input type="hidden" name="cmd" /> + <input type="hidden" name="markcopy" /> + <input type="hidden" name="copyfolder" /> + $containertag + </form> + +HIDDENFORM + $r->print(&makesimpleeditform($uploadtag)."\n". + &makedocslogform($uploadtag."\n". + '<input type="hidden" name="folder" value="'. + $env{'form.folder'}.'" />'."\n")); + } + +# Generate the tabs + my $mode; + if (($supplementalflag) && (!$allowed)) { + &Apache::lonnavdisplay::startContentScreen($r,'supplemental'); + } else { + $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs'))); + } - my $folderpath=$env{'form.folderpath'}; - if (!$folderpath) { - if ($env{'form.folder'} eq '' || - $env{'form.folder'} eq 'supplemental') { - $folderpath='default&'. - &escape(&mt('Main '.$type.' Documents')); - } - } - unless ($env{'form.pagepath'}) { - $containertag = '<input type="hidden" name="folderpath" value="" />'; - $uploadtag = '<input type="hidden" name="folderpath" value="'.$folderpath.'" />'; - } +# + + my $savefolderpath; - $r->print(<<ENDCOURSEVERIFY); -<form name="renameform" method="post" action="/adm/coursedocs"> -<input type="hidden" name="title" /> -<input type="hidden" name="cmd" /> -<input type="hidden" name="markcopy" /> -$containertag -</form> -<form name="simpleedit" method="post" action="/adm/coursedocs"> -<input type=hidden name="importdetail" value=""> -$uploadtag -</form> -<form action="/adm/coursedocs" method="post" name="courseverify"> -<table bgcolor="#AAAAAA" width="100%" cellspacing="4" cellpadding="4"> -<tr><td bgcolor="#DDDDCC"> -<input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'} -</td><td bgcolor="#DDDDCC"> - <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'} -$dumpbut -$exportbut -</td><td bgcolor="#DDDDCC"> - <input type="submit" name="listsymbs" value="$lt{'ls'}" /> -</td></tr></table> -</form> -ENDCOURSEVERIFY - $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc', - &mt('Editing the Table of Contents for your '.$type))); - } -# --------------------------------------------------------- Standard documents - $r->print('<table border=2 cellspacing=4 cellpadding=4>'); - if (($standard) && ($allowed) && (!$forcesupplement)) { - $r->print('<tr><td bgcolor="#BBBBBB">'); -# '<h2>'.&mt('Main Course Documents'). -# ($allowed?' '.$help{'Main_Course_Documents'}:'').'</h2>'); + if ($allowed) { my $folder=$env{'form.folder'}; - if ($folder eq '' || $folder eq 'supplemental') { + if ($folder eq '' || $supplementalflag) { $folder='default'; - $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$type.' Documents')); + $savefolderpath = $env{'form.folderpath'}; + $env{'form.folderpath'}='default&'.&escape(&mt('Content')); + $uploadtag = '<input type="hidden" name="folderpath" value="'. + &HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />'; } my $postexec=''; if ($folder eq 'default') { - $r->print('<script>this.window.name="loncapaclient";</script>'); + $r->print('<script type="text/javascript">'."\n" + .'// <![CDATA['."\n" + .'this.window.name="loncapaclient";'."\n" + .'// ]]>'."\n" + .'</script>'."\n" + ); } else { #$postexec='self.close();'; } - $hadchanges=0; - &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output); - if ($hadchanges) { - &mark_hash_old() - } - &changewarning($r,$postexec); my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. '.sequence'; my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. @@ -2413,321 +3292,702 @@ ENDCOURSEVERIFY $container='page'; } my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container; - $r->print(<<ENDFORM); -<table cellspacing=4 cellpadding=4><tr> -<th bgcolor="#DDDDDD">$lt{'uplm'}</th> -<th bgcolor="#DDDDDD">$lt{'impp'}</th> -<th bgcolor="#DDDDDD">$lt{'spec'}</th> -</tr> -<tr><td bgcolor="#DDDDDD"> -$lt{'file'}:<br /> -<form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data"> -<input type="file" name="uploaddoc" size="40"> -<br /> -$lt{'title'}:<br /> -<input type="text" size="50" name="comment"> -$uploadtag -<input type="hidden" name="cmd" value="upload_default"> -<br /> -<nobr> -<label>$lt{'parse'}? -<input type="checkbox" name="parserflag" /> -</label> -</nobr> -<br /> -<br /> -<nobr> -<input type="submit" value="$lt{'upld'}"> - $help{'Uploading_From_Harddrive'} -</nobr> -</form> -</td> -<td bgcolor="#DDDDDD"> -<form action="/adm/coursedocs" method="post" name="simpleeditdefault"> -$lt{'pubd'}<br /> -$uploadtag -<input type=button onClick="javascript:groupsearch()" value="$lt{'srch'}" /> -<br /> -<nobr> -<input type=button onClick="javascript:groupimport();" value="$lt{'impo'}" /> -$help{'Importing_LON-CAPA_Resource'} -</nobr> -<br /> -<input type=button onClick="javascript:groupopen(0,1,1);" value="$lt{'book'}" /> -<p> -<hr /> -$lt{'copm'}<br /> -<input type="text" size="40" name="importmap"><br /> -<nobr><input type=button -onClick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')" -value="$lt{'selm'}"> <input type="submit" name="loadmap" value="$lt{'load'}"> -$help{'Load_Map'}</nobr> -</p> -</form> -<hr /> -<form action="/adm/groupsort" method="post" name="recover"> -<input type="button" name="recovermap" onClick="javascript:groupopen('$readfile',1,0)" value="$lt{'reco'}" /> -</form> -ENDFORM - unless ($env{'form.pagepath'}) { - $r->print(<<ENDFORM); -<hr /> -<form action="/adm/coursedocs" method="post" name="newext"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newext" type="button" onClick="javascript:makenewext('newext');" -value="$lt{'extr'}" /> $help{'Adding_External_Resource'} -</nobr> -</form> -<br /><form action="/adm/imsimportdocs" method="post" name="ims"> -<input type="hidden" name="folder" value="$folder" /> -<input name="imsimport" type="button" value="$lt{'imsf'}" onClick="javascript:makeims();" /> -</nobr> -</form> -ENDFORM - } - $r->print('</td><td bgcolor="#DDDDDD">'); - unless ($env{'form.pagepath'}) { - $r->print(<<ENDFORM); -<br /><form action="/adm/coursedocs" method="post" name="newfolder"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newfolder" type="button" -onClick="javascript:makenewfolder(this.form,'$folderseq');" -value="$lt{'newf'}" />$help{'Adding_Folders'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newpage"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newpage" type="button" -onClick="javascript:makenewpage(this.form,'$pageseq');" -value="$lt{'newp'}" />$help{'Adding_Pages'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newsyl"> -$uploadtag -<input type=hidden name="importdetail" -value="Syllabus=/public/$coursedom/$coursenum/syllabus"> -<nobr> -<input name="newsyl" type="submit" value="$lt{'syll'}" /> - $help{'Syllabus'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newnav"> -$uploadtag -<input type=hidden name="importdetail" -value="Navigate Content=/adm/navmaps"> -<nobr> -<input name="newnav" type="submit" value="$lt{'navc'}" /> -$help{'Navigate_Content'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newsmppg"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newsmppg" type="button" value="$lt{'sipa'}" -onClick="javascript:makesmppage();" /> $help{'Simple Page'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newsmpproblem"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newsmpproblem" type="button" value="$lt{'sipr'}" -onClick="javascript:makesmpproblem();" />$help{'Simple Problem'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newdropbox"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newdropbox" type="button" value="$lt{'drbx'}" -onClick="javascript:makedropbox();" /> -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newexamupload"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newexamupload" type="button" value="$lt{'scuf'}" -onClick="javascript:makeexamupload();" /> -$help{'Score_Upload_Form'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newbul"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newbulletin" type="button" value="$lt{'bull'}" -onClick="javascript:makebulboard();" /> -$help{'Bulletin Board'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newaboutme"> -$uploadtag -<input type=hidden name="importdetail" -value="$plainname=/adm/$udom/$uname/aboutme"> -<nobr> -<input name="newaboutme" type="submit" value="$lt{'mypi'}" /> -$help{'My Personal Info'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newaboutsomeone"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newaboutsomeone" type="button" value="$lt{'abou'}" -onClick="javascript:makeabout();" /> -</nobr> -</form> -ENDFORM - } - if ($env{'form.pagepath'}) { - $r->print(<<ENDBLOCK); -<form action="/adm/coursedocs" method="post" name="newsmpproblem"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newsmpproblem" type="button" value="$lt{'sipr'}" -onClick="javascript:makesmpproblem();" />$help{'Simple Problem'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="newexamupload"> -$uploadtag -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newexamupload" type="button" value="$lt{'scuf'}" -onClick="javascript:makeexamupload();" /> -$help{'Score_Upload_Form'} -</nobr> -</form> -ENDBLOCK - } - $r->print('</td></tr>'."\n". -'</table>'); - $r->print('</td></tr>'); - } -# ----------------------------------------------------- Supplemental documents - if (!$forcestandard) { - $r->print('<tr><td bgcolor="#BBBBBB">'); -# '<h2>'.&mt('Supplemental Course Documents'). -# ($allowed?' '.$help{'Supplemental'}:'').'</h2>'); + + my $imspform=(<<IMSPFORM); + <form action="/adm/imsimportdocs" method="post" name="ims"> + <input type="hidden" name="folder" value="$folder" /> + <a class="LC_menubuttons_link" href="javascript:makeims();">$lt{'imsf'}</a> + </form> +IMSPFORM + + my $newnavform=(<<NNFORM); + <form action="/adm/coursedocs" method="post" name="newnav"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" + value="$lt{'navc'}=/adm/navmaps" /> + <a class="LC_menubuttons_link" href="javascript:document.newnav.submit()">$lt{'navc'}</a> + $help{'Navigate_Content'} + </form> +NNFORM + my $newsmppageform=(<<NSPFORM); + <form action="/adm/coursedocs" method="post" name="newsmppg"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makesmppage();"> $lt{'sipa'}</a> + $help{'Simple Page'} + </form> +NSPFORM + + my $newsmpproblemform=(<<NSPROBFORM); + <form action="/adm/coursedocs" method="post" name="newsmpproblem"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makesmpproblem();">$lt{'sipr'}</a> + $help{'Simple Problem'} + </form> + +NSPROBFORM + + my $newdropboxform=(<<NDBFORM); + <form action="/adm/coursedocs" method="post" name="newdropbox"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makedropbox();">$lt{'drbx'}</a> + </form> +NDBFORM + + my $newexuploadform=(<<NEXUFORM); + <form action="/adm/coursedocs" method="post" name="newexamupload"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makeexamupload();">$lt{'scuf'}</a> + $help{'Score_Upload_Form'} + </form> +NEXUFORM + + my $newbulform=(<<NBFORM); + <form action="/adm/coursedocs" method="post" name="newbul"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makebulboard();" >$lt{'bull'}</a> + $help{'Bulletin Board'} + </form> +NBFORM + + my $newaboutmeform=(<<NAMFORM); + <form action="/adm/coursedocs" method="post" name="newaboutme"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" + value="$plainname=/adm/$udom/$uname/aboutme" /> + <a class="LC_menubuttons_link" href="javascript:document.newaboutme.submit()">$lt{'mypi'}</a> + $help{'My Personal Information Page'} + </form> +NAMFORM + + my $newaboutsomeoneform=(<<NASOFORM); + <form action="/adm/coursedocs" method="post" name="newaboutsomeone"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makeabout();">$lt{'abou'}</a> + </form> +NASOFORM + + + my $newrosterform=(<<NROSTFORM); + <form action="/adm/coursedocs" method="post" name="newroster"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" + value="$lt{'rost'}=/adm/viewclasslist" /> + <a class="LC_menubuttons_link" href="javascript:document.newroster.submit()">$lt{'rost'}</a> + $help{'Course Roster'} + </form> +NROSTFORM + +my $specialdocumentsform; +my @specialdocumentsforma; +my $gradingform; +my @gradingforma; +my $communityform; +my @communityforma; +my $newfolderform; +my $newfolderb; + + my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + + my $newpageform=(<<NPFORM); + <form action="/adm/coursedocs" method="post" name="newpage"> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" value="" /> + <input type="hidden" name="active" value="cc" /> + <a class="LC_menubuttons_link" href="javascript:makenewpage(document.newpage,'$pageseq');">$lt{'newp'}</a> + $help{'Adding_Pages'} + </form> +NPFORM + + + $newfolderform=(<<NFFORM); + <form action="/adm/coursedocs" method="post" name="newfolder"> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" value="" /> + <input type="hidden" name="active" value="aa" /> + <a href="javascript:makenewfolder(document.newfolder,'$folderseq');">$lt{'newf'}</a>$help{'Adding_Folders'} + </form> +NFFORM + + my $newsylform=(<<NSYLFORM); + <form action="/adm/coursedocs" method="post" name="newsyl"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" + value="$lt{'syll'}=/public/$coursedom/$coursenum/syllabus" /> + <a class="LC_menubuttons_link" href="javascript:document.newsyl.submit()">$lt{'syll'}</a> + $help{'Syllabus'} + + </form> +NSYLFORM + + my $newgroupfileform=(<<NGFFORM); + <form action="/adm/coursedocs" method="post" name="newgroupfiles"> + <input type="hidden" name="active" value="cc" /> + $uploadtag + <input type="hidden" name="importdetail" + value="$lt{'grpo'}=/adm/$coursedom/$coursenum/aboutme" /> + <a class="LC_menubuttons_link" href="javascript:document.newgroupfiles.submit()">$lt{'grpo'}</a> + $help{'Group Portfolio'} + </form> +NGFFORM + @specialdocumentsforma=( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/page.png" alt="'.$lt{newp}.'" onclick="javascript:makenewpage(document.newpage,\''.$pageseq.'\');" />'=>$newpageform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/syllabus.png" alt="'.$lt{syll}.'" onclick="document.newsyl.submit()" />'=>$newsylform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/navigation.png" alt="'.$lt{navc}.'" onclick="document.newnav.submit()" />'=>$newnavform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/simple.png" alt="'.$lt{sipa}.'" onclick="javascript:makesmppage();" />'=>$newsmppageform}, + ); + $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma)); + + + my @importdoc = ( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:makenewext(\'newext\');" />'=>$extresourcesform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/ims.png" alt="'.$lt{imsf}.'" onclick="javascript:makeims();" />'=>$imspform},); + $fileuploadform = &create_form_ul(&create_list_elements(@importdoc)) . '<hr id="cc_hrule" style="width:0px;text-align:left;margin-left:0" />' . $fileuploadform; + + @gradingforma=( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/simpprob.png" alt="'.$lt{sipr}.'" onclick="javascript:makesmpproblem();" />'=>$newsmpproblemform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/dropbox.png" alt="'.$lt{drbx}.'" onclick="javascript:makedropbox();" />'=>$newdropboxform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/scoreupfrm.png" alt="'.$lt{scuf}.'" onclick="javascript:makeexamupload();" />'=>$newexuploadform}, + + ); + $gradingform = &create_form_ul(&create_list_elements(@gradingforma)); + + @communityforma=( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/bchat.png" alt="'.$lt{bull}.'" onclick="javascript:makebulboard();" />'=>$newbulform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/myaboutme.png" alt="'.$lt{mypi}.'" onclick="javascript:makebulboard();" />'=>$newaboutmeform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/aboutme.png" alt="'.$lt{abou}.'" onclick="javascript:makeabout();" />'=>$newaboutsomeoneform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/clst.png" alt="'.$lt{rost}.'" onclick="document.newroster.submit()" />'=>$newrosterform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/groupportfolio.png" alt="'.$lt{grpo}.'" onclick="document.newgroupfiles.submit()" />'=>$newgroupfileform}, + ); + $communityform = &create_form_ul(&create_list_elements(@communityforma)); + +my %orderhash = ( + 'aa' => ['Import Content',$fileuploadform], + 'bb' => ['Published Content',$simpleeditdefaultform], + 'cc' => ['Grading Resources',$gradingform], + ); +unless ($env{'form.pagepath'}) { + $orderhash{'00'} = ['Newfolder',$newfolderform]; + $orderhash{'dd'} = ['Collaboration',$communityform]; + $orderhash{'ee'} = ['Special Documents',$specialdocumentsform]; +} + + $hadchanges=0; + unless (($supplementalflag || $toolsflag)) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,\%orderhash,$iconpath); + if ($error) { + $r->print('<p><span class="LC_error">'.$error.'</span></p>'); + } + if ($hadchanges) { + &mark_hash_old(); + } + + &changewarning($r,''); + } + } + +# Supplemental documents start here + my $folder=$env{'form.folder'}; - unless ($folder=~/^supplemental/) { + unless ($supplementalflag) { $folder='supplemental'; } if ($folder =~ /^supplemental$/ && - $env{'form.folderpath'} =~ /^default\&/) { - $env{'form.folderpath'}='supplemental&'. - &escape(&mt('Supplemental '.$type.' Documents')); + (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) { + $env{'form.folderpath'} = &supplemental_base(); + } elsif ($allowed) { + $env{'form.folderpath'} = $savefolderpath; } - &editor($r,$coursenum,$coursedom,$folder,$allowed); + $env{'form.pagepath'} = ''; if ($allowed) { - my $folderseq= - '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time. - '.sequence'; - - $r->print(<<ENDSUPFORM); -<table cellspacing=4 cellpadding=4><tr> -<th bgcolor="#DDDDDD">$lt{'upls'}</th> -<th bgcolor="#DDDDDD">$lt{'spec'}</th> -</tr> -<tr><td bgcolor="#DDDDDD"> -<form action="/adm/coursedocs" method="post" enctype="multipart/form-data"> -<input type="file" name="uploaddoc" size="40"> -<br /> -<br /> -<nobr> -<label>$lt{'parse'}? -<input type="checkbox" name="parserflag" /> -</label> -</nobr> -<br /><br /> -$lt{'comment'}:<br /> -<textarea cols=50 rows=4 name='comment'> -</textarea> -<br /> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type="hidden" name="cmd" value="upload_supplemental"> -<nobr> -<input type="submit" value="$lt{'upld'}"> - $help{'Uploading_From_Harddrive'} -</nobr> -</form> -</td> -<td bgcolor="#DDDDDD"> -<form action="/adm/coursedocs" method="post" name="supnewfolder"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newfolder" type="button" -onClick="javascript:makenewfolder(this.form,'$folderseq');" -value="$lt{'newf'}" /> $help{'Adding_Folders'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="supnewext"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" value=""> -<nobr> -<input name="newext" type="button" -onClick="javascript:makenewext('supnewext');" -value="$lt{'extr'}" /> $help{'Adding_External_Resource'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="supnewsyl"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" -value="Syllabus=/public/$coursedom/$coursenum/syllabus"> -<nobr> -<input name="newsyl" type="submit" value="$lt{'syll'}" /> -$help{'Syllabus'} -</nobr> -</form> -<br /><form action="/adm/coursedocs" method="post" name="subnewaboutme"> -<input type="hidden" name="folderpath" value="$env{'form.folderpath'}" /> -<input type=hidden name="importdetail" -value="$plainname=/adm/$udom/$uname/aboutme"> -<nobr> -<input name="newaboutme" type="submit" value="$lt{'mypi'}" /> -$help{'My Personal Info'} -</nobr> -</form> -</td></tr> -</table></td></tr> -ENDSUPFORM - } + my $folderseq= + '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time. + '.sequence'; + + my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + + my $supupdocformbtn = "<input type='submit' value='".$lt{'upld'}."' />$help{'Uploading_From_Harddrive'}"; + my $supupdocform=(<<SUPDOCFORM); + <form action="/adm/coursedocs" method="post" name="supuploaddocument" enctype="multipart/form-data"> + <input type="hidden" name="active" value="ee" /> + $fileupload + <br /> + <br /> + <span class="LC_nobreak"> + $checkbox + </span> + <br /><br /> + $lt{'comment'}:<br /> + <textarea cols="50" rows="4" name="comment"></textarea> + <br /> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="cmd" value="upload_supplemental" /> +SUPDOCFORM + $supupdocform .= &create_form_ul(&Apache::lonhtmlcommon::htmltag('li',$supupdocformbtn,{class => 'LC_menubuttons_inline_text'}))."</form>"; + + my $supnewfolderform=(<<SNFFORM); + <form action="/adm/coursedocs" method="post" name="supnewfolder"> + <input type="hidden" name="active" value="ee" /> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makenewfolder(document.supnewfolder,'$folderseq');">$lt{'newf'}</a> + $help{'Adding_Folders'} + </form> +SNFFORM + + + my $supnewextform=(<<SNEFORM); + <form action="/adm/coursedocs" method="post" name="supnewext"> + <input type="hidden" name="active" value="ff" /> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" value="" /> + <a class="LC_menubuttons_link" href="javascript:makenewext('supnewext');">$lt{'extr'}</a> $help{'Adding_External_Resource'} + </form> +SNEFORM + + my $supnewsylform=(<<SNSFORM); + <form action="/adm/coursedocs" method="post" name="supnewsyl"> + <input type="hidden" name="active" value="ff" /> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" + value="Syllabus=/public/$coursedom/$coursenum/syllabus" /> + <a class="LC_menubuttons_link" href="javascript:document.supnewsyl.submit()">$lt{'syll'}</a> + $help{'Syllabus'} + </form> +SNSFORM + + my $supnewaboutmeform=(<<SNAMFORM); + <form action="/adm/coursedocs" method="post" name="supnewaboutme"> + <input type="hidden" name="active" value="ff" /> + <input type="hidden" name="folderpath" value="$path" /> + <input type="hidden" name="importdetail" + value="$plainname=/adm/$udom/$uname/aboutme" /> + <a class="LC_menubuttons_link" href="javascript:document.supnewaboutme.submit()">$lt{'mypi'}</a> + $help{'My Personal Information Page'} + </form> +SNAMFORM + + +my @specialdocs = ( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/syllabus.png" alt="'.$lt{syll}.'" onclick="document.supnewsyl.submit()" />' + =>$supnewsylform}, + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/myaboutme.png" alt="'.$lt{mypi}.'" onclick="document.supnewaboutme.submit()" />' + =>$supnewaboutmeform}, + ); +my @supimportdoc = ( + {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:makenewext(\'supnewext\');" />' + =>$supnewextform}, + ); +$supupdocform = &create_form_ul(&create_list_elements(@supimportdoc)) . '<hr id="ee_hrule" style="width:0px;text-align:left;margin-left:0" />' . $supupdocform; +my %suporderhash = ( + '00' => ['Supnewfolder', $supnewfolderform], + 'ee' => ['Import Content',$supupdocform], + 'ff' => ['Special Documents',&create_form_ul(&create_list_elements(@specialdocs))] + ); + if ($supplementalflag) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,\%suporderhash,$iconpath); + if ($error) { + $r->print('<p><span class="LC_error">'.$error.'</span></p>'); + } + } + } elsif ($supplementalflag) { + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,'',$iconpath); + if ($error) { + $r->print('<p><span class="LC_error">'.$error.'</span></p>'); + } } + + $r->print(&endContentScreen()); + if ($allowed) { - $r->print('<form method="POST" name="extimport" action="/adm/coursedocs"><input type="hidden" name="title" /><input type="hidden" name="url" /><input type="hidden" name="useform" /></form>'); + $r->print(' +<form method="post" name="extimport" action="/adm/coursedocs"> + <input type="hidden" name="title" /> + <input type="hidden" name="url" /> + <input type="hidden" name="useform" /> + <input type="hidden" name="residx" /> +</form>'); } - $r->print('</table>'); - } else { - unless ($upload_result eq 'phasetwo') { + } elsif ($showdoc) { # -------------------------------------------------------- This is showdoc mode - $r->print("<h1>".&mt('Uploaded Document').' - '. + $r->print("<h1>".&mt('Uploaded Document').' - '. &Apache::lonnet::gettitle($r->uri).'</h1><p>'. -&mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><p><table>". - &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table></p>'); - } +&mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><table>". + &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table>'); } } $r->print(&Apache::loncommon::end_page()); return OK; -} +} +sub embedded_form_elems { + my ($phase,$primaryurl,$newidx) = @_; + my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + return <<STATE; + <input type="hidden" name="folderpath" value="$folderpath" /> + <input type="hidden" name="cmd" value="upload_embedded" /> + <input type="hidden" name="newidx" value="$newidx" /> + <input type="hidden" name="phase" value="$phase" /> + <input type="hidden" name="primaryurl" value="$primaryurl" /> +STATE +} + +sub embedded_destination { + my $folder=$env{'form.folder'}; + my $destination = 'docs/'; + if ($folder =~ /^supplemental/) { + $destination = 'supplemental/'; + } + if (($folder eq 'default') || ($folder eq 'supplemental')) { + $destination .= 'default/'; + } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { + $destination .= $2.'/'; + } + $destination .= $env{'form.newidx'}; + my $dir_root = '/userfiles'; + return ($destination,$dir_root); +} + +sub return_to_editor { + my $actionurl = '/adm/coursedocs'; + return '<p><form name="backtoeditor" method="post" action="'.$actionurl.'" />'."\n". + '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" /></form>'."\n". + '<a href="javascript:document.backtoeditor.submit();">'.&mt('Return to Editor'). + '</a></p>'; +} + +sub decompression_info { + my ($destination,$dir_root) = &embedded_destination(); + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $container='sequence'; + my ($pathitem,$hiddenelem); + my @hiddens = ('newidx','comment','position'); + if ($env{'form.pagepath'}) { + $container='page'; + $pathitem = 'pagepath'; + } else { + $pathitem = 'folderpath'; + } + unshift(@hiddens,$pathitem); + foreach my $item (@hiddens) { + if ($env{'form.'.$item}) { + $hiddenelem .= '<input type="hidden" name="'.$item.'" value="'. + $env{'form.'.$item}.'" />'."\n"; + } + } + return ($destination,$dir_root,$londocroot,$docudom,$docuname,$container, + $hiddenelem); +} + +sub decompression_phase_one { + my ($dir,$file,$warning,$error,$output); + my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)= + &decompression_info(); + if ($env{'form.archiveurl'} !~ m{^/uploaded/\Q$docudom/$docuname/\E(?:docs|supplemental)/(?:default|\d+).*/([^/]+)$}) { + $error = &mt('Archive file "[_1]" not in the expected location.',$env{'form.archiveurl'}); + } else { + my $file = $1; + $output = + &Apache::loncommon::process_decompression($docudom,$docuname,$file, + $destination,$dir_root, + $hiddenelem); + if ($env{'form.autoextract_camtasia'}) { + $output .= &remove_archive($docudom,$docuname,$container); + } + } + if ($error) { + $output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'. + $error.'</p>'."\n"; + } + if ($warning) { + $output .= '<p class="LC_warning">'.$warning.'</p>'."\n"; + } + return $output; +} + +sub decompression_phase_two { + my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)= + &decompression_info(); + my $output; + if ($env{'form.archivedelete'}) { + $output = &remove_archive($docudom,$docuname,$container); + } + $output .= + &Apache::loncommon::process_extracted_files('coursedocs',$docudom,$docuname, + $destination,$dir_root,$hiddenelem); + return $output; +} + +sub remove_archive { + my ($docudom,$docuname,$container) = @_; + my $map = $env{'form.folder'}.'.'.$container; + my ($output,$delwarning,$delresult,$url); + my ($errtext,$fatal) = &mapread($docuname,$docudom,$map); + if ($fatal) { + if ($container eq 'page') { + $delwarning = &mt('An error occurred retrieving the contents of the current page.'); + } else { + $delwarning = &mt('An error occurred retrieving the contents of the current folder.'); + } + $delwarning .= &mt('As a result the archive file has not been removed.'); + } else { + my $currcmd = $env{'form.cmd'}; + my $position = $env{'form.position'}; + if ($position > 0) { + $env{'form.cmd'} = 'del_'.$position; + my ($title,$url,@rrest) = + split(/:/,$LONCAPA::map::resources[$LONCAPA::map::order[$position]]); + if (&handle_edit_cmd($docuname,$docudom)) { + ($errtext,$fatal) = &storemap($docuname,$docudom,$map); + if ($fatal) { + if ($container eq 'page') { + $delwarning = &mt('An error occurred updating the contents of the current page.'); + } else { + $delwarning = &mt('An error occurred updating the contents of the current folder.'); + } + } else { + $delresult = &mt('Archive file removed.'); + } + } + } + $env{'form.cmd'} = $currcmd; + } + if ($delwarning) { + $output = '<p class="LC_warning">'. + $delwarning. + '</p>'; + } + if ($delresult) { + $output .= '<p class="LC_info">'. + $delresult. + '</p>'; + } + return $output; +} + +sub generate_admin_menu { + my ($crstype) = @_; + my $lc_crstype = lc($crstype); + my ($home,$other,%outhash)=&authorhosts(); + my %lt=&Apache::lonlocal::texthash ( + 'vc' => 'Verify Content', + 'cv' => 'Check/Set Resource Versions', + 'ls' => 'List Resource Identifiers', + 'imse' => 'Export contents to IMS Archive', + 'dcd' => "Dump $crstype Content to Authoring Space", + ); + my ($candump,$dumpurl); + if ($home + $other > 0) { + $candump = 'F'; + if ($home) { + $dumpurl = "javascript:injectData(document.courseverify,'dummy','dumpcourse','$lt{'dcd'}')"; + } else { + my @hosts; + foreach my $aurole (keys(%outhash)) { + unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) { + push(@hosts,$outhash{$aurole}); + } + } + if (@hosts == 1) { + my $switchto = '/adm/switchserver?otherserver='.$hosts[0]. + '&role='. + &HTML::Entities::encode($env{'request.role'},'"<>&').'&origurl='. + &HTML::Entities::encode('/adm/coursedocs?dumpcourse=1','"<>&'); + $dumpurl = "javascript:dump_needs_switchserver('$switchto')"; + } else { + $dumpurl = "javascript:choose_switchserver_window()"; + } + } + } + my @menu= + ({ categorytitle=>'Administration', + items =>[ + { linktext => $lt{'vc'}, + url => "javascript:injectData(document.courseverify,'dummy','verify','$lt{'vc'}')", + permission => 'F', + help => 'Verify_Content', + icon => 'verify.png', + linktitle => 'Verify contents can be retrieved/rendered', + }, + { linktext => $lt{'cv'}, + url => "javascript:injectData(document.courseverify,'dummy','versions','$lt{'cv'}')", + permission => 'F', + help => 'Check_Resource_Versions', + icon => 'resversion.png', + linktitle => "View version information for resources in your $lc_crstype, and fix/unfix use of specific versions", + }, + { linktext => $lt{'ls'}, + url => "javascript:injectData(document.courseverify,'dummy','listsymbs','$lt{'ls'}')", + permission => 'F', + #help => '', + icon => 'symbs.png', + linktitle => "List the unique identifier used for each resource instance in your $lc_crstype" + }, + ] + }, + { categorytitle=>'Export', + items =>[ + { linktext => $lt{'imse'}, + url => "javascript:injectData(document.courseverify,'dummy','exportcourse','$lt{'imse'}')", + permission => 'F', + help => 'Docs_Export_Course_Docs', + icon => 'imsexport.png', + linktitle => $lt{'imse'}, + }, + { linktext => $lt{'dcd'}, + url => $dumpurl, + permission => $candump, + #help => '', + icon => 'dump.png', + linktitle => $lt{'dcd'}, + }, + ] + }); + return '<form action="/adm/coursedocs" method="post" name="courseverify">'."\n". + '<input type="hidden" id="dummy" />'."\n". + &Apache::lonhtmlcommon::generate_menu(@menu)."\n". + '</form>'; +} + +sub generate_edit_table { + my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile) = @_; + return unless(ref($orderhash_ref) eq 'HASH'); + my %orderhash = %{$orderhash_ref}; + my $form; + my $activetab; + my $active; + if($env{'form.active'} ne ''){ + $activetab = $env{'form.active'}; + } + my $backicon = $iconpath.'clickhere.gif'; + my $backtext = &mt('To Overview'); + $form = '<div class="LC_Box" style="margin:0;">'. + '<ul id="navigation'.$tid.'" class="LC_TabContent">'."\n". + '<li class="goback">'. + '<a href="javascript:toContents('."'$jumpto'".');">'. + '<img src="'.$backicon.'" class="LC_icon" style="border: none; vertical-align: top;"'. + ' alt="'.$backtext.'" />'.$backtext.'</a></li>'."\n". + '<li>'. + '<a href="javascript:groupopen('."'$readfile'".',1);">'. + &mt('Undo Delete').'</a></li>'."\n"; + if ($env{'form.docslog'}) { + $form .= '<li class="active">'; + } else { + $form .= '<li>'; + } + $form .= '<a href="javascript:toggleHistoryDisp(1);">'. + &mt('History').'</a></li>'."\n"; + if ($env{'form.docslog'}) { + $form .= '<li><a href="javascript:toggleHistoryDisp(0);">'. + &mt('Edit').'</a></li>'."\n"; + } + foreach my $name (reverse(sort(keys(%orderhash)))) { + if($name ne '00'){ + if($activetab eq '' || $activetab ne $name){ + $active = ''; + }elsif($activetab eq $name){ + $active = 'class="active"'; + } + $form .= '<li style="float:right" '.$active + .' onmouseover="javascript:showPage(this, \''.$name.$tid.'\', \'navigation'.$tid.'\',\'content'.$tid.'\');"' + .' onclick="javascript:showPage(this, \''.$name.$tid.'\', \'navigation'.$tid.'\',\'content'.$tid.'\');"><a href="javascript:;"><b>'.&mt(${$orderhash{$name}}[0]).'</b></a></li>'."\n"; + } else { + $form .= '<li '.$active.' style="float:right">'.${$orderhash{$name}}[1].'</li>'."\n"; + + } + } + $form .= '</ul>'."\n"; + $form .= '<div id="content'.$tid.'" style="padding: 0 0; margin: 0 0; overflow: hidden; clear:right">'."\n"; + + if ($to_show ne '') { + $form .= '<div style="padding:0;margin:0;float:left">'.$to_show.'</div>'."\n"; + } + foreach my $field (keys(%orderhash)){ + if($field ne '00'){ + if($activetab eq '' || $activetab ne $field){ + $active = 'style="display: none;float:left"'; + }elsif($activetab eq $field){ + $active = 'style="display:block;float:left"'; + } + $form .= '<div id="'.$field.$tid.'"' + .' class="LC_ContentBox" '.$active.'>'.${$orderhash{$field}}[1] + .'</div>'."\n"; + } + } + unless ($env{'form.docslog'}) { + $form .= '</div></div>'."\n"; + } + return $form; +} sub editing_js { - my ($udom,$uname) = @_; + my ($udom,$uname,$supplementalflag) = @_; my $now = time(); + my %lt = &Apache::lonlocal::texthash( + p_mnf => 'Name of New Folder', + t_mnf => 'New Folder', + p_mnp => 'Name of New Page', + t_mnp => 'New Page', + p_mxu => 'Title for the External Score', + p_msp => 'Name of Simple Course Page', + p_msb => 'Title for the Problem', + p_mdb => 'Title for the Drop Box', + p_mbb => 'Title for the Discussion Board', + p_mab => "Enter user:domain for User's Personal Information Page", + p_mab2 => 'Personal Information Page of ', + p_mab_alrt1 => 'Not a valid user:domain', + p_mab_alrt2 => 'Please enter both user and domain in the format user:domain', + p_chn => 'New Title', + p_rmr1 => 'WARNING: Removing a resource makes associated grades and scores inaccessible!', + p_rmr2a => 'Remove[_99]', + p_rmr2b => '?[_99]', + p_ctr1a => 'WARNING: Cutting a resource makes associated grades and scores inaccessible!', + p_ctr1b => 'Grades remain inaccessible if resource is pasted into another folder.', + p_ctr2a => 'Cut[_98]', + p_ctr2b => '?[_98]', + rpck => 'Enter number to pick (e.g., 3)', + ); + + my $crstype = &Apache::loncommon::course_type(); + my $docs_folderpath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'},'<>&"'); + my $docs_pagepath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.pagepath'},'<>&"'); + my $main_container_page; + if ($docs_folderpath eq '') { + if ($docs_pagepath ne '') { + $main_container_page = 1; + } + } + my $toplevelmain = 'default&Main%20'.$crstype.'%20Documents'; + my $toplevelsupp = &supplemental_base(); + + my $backtourl = '/adm/navmaps'; + if ($supplementalflag) { + $backtourl = '/adm/supplemental'; + } return <<ENDNEWSCRIPT; function makenewfolder(targetform,folderseq) { - var foldername=prompt('Name of New Folder','New Folder'); + var foldername=prompt('$lt{"p_mnf"}','$lt{"t_mnf"}'); if (foldername) { targetform.importdetail.value=escape(foldername)+"="+folderseq; targetform.submit(); @@ -2735,7 +3995,7 @@ function makenewfolder(targetform,folder } function makenewpage(targetform,folderseq) { - var pagename=prompt('Name of New Page','New Page'); + var pagename=prompt('$lt{"p_mnp"}','$lt{"t_mnp"}'); if (pagename) { targetform.importdetail.value=escape(pagename)+"="+folderseq; targetform.submit(); @@ -2744,12 +4004,23 @@ function makenewpage(targetform,folderse function makenewext(targetname) { this.document.forms.extimport.useform.value=targetname; + this.document.forms.extimport.title.value=''; + this.document.forms.extimport.url.value=''; + this.document.forms.extimport.residx.value=''; + window.open('/adm/rat/extpickframe.html'); +} + +function edittext(targetname,residx,title,url) { + this.document.forms.extimport.useform.value=targetname; + this.document.forms.extimport.residx.value=residx; + this.document.forms.extimport.url.value=url; + this.document.forms.extimport.title.value=title; window.open('/adm/rat/extpickframe.html'); } function makeexamupload() { - var title=prompt('Listed Title for the Uploaded Score'); - if (title) { + var title=prompt('$lt{"p_mxu"}'); + if (title) { this.document.forms.newexamupload.importdetail.value= escape(title)+'=/res/lib/templates/examupload.problem'; this.document.forms.newexamupload.submit(); @@ -2757,8 +4028,8 @@ function makeexamupload() { } function makesmppage() { - var title=prompt('Listed Title for the Page'); - if (title) { + var title=prompt('$lt{"p_msp"}'); + if (title) { this.document.forms.newsmppg.importdetail.value= escape(title)+'=/adm/$udom/$uname/$now/smppg'; this.document.forms.newsmppg.submit(); @@ -2766,8 +4037,8 @@ function makesmppage() { } function makesmpproblem() { - var title=prompt('Listed Title for the Problem'); - if (title) { + var title=prompt('$lt{"p_msb"}'); + if (title) { this.document.forms.newsmpproblem.importdetail.value= escape(title)+'=/res/lib/templates/simpleproblem.problem'; this.document.forms.newsmpproblem.submit(); @@ -2775,8 +4046,8 @@ function makesmpproblem() { } function makedropbox() { - var title=prompt('Listed Title for the Drop Box'); - if (title) { + var title=prompt('$lt{"p_mdb"}'); + if (title) { this.document.forms.newdropbox.importdetail.value= escape(title)+'=/res/lib/templates/DropBox.problem'; this.document.forms.newdropbox.submit(); @@ -2784,7 +4055,7 @@ function makedropbox() { } function makebulboard() { - var title=prompt('Listed Title for the Bulletin Board'); + var title=prompt('$lt{"p_mbb"}'); if (title) { this.document.forms.newbul.importdetail.value= escape(title)+'=/adm/$udom/$uname/$now/bulletinboard'; @@ -2793,99 +4064,498 @@ function makebulboard() { } function makeabout() { - var user=prompt("Enter user:domain for User's 'About Me' Page"); + var user=prompt("$lt{'p_mab'}"); if (user) { var comp=new Array(); comp=user.split(':'); if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) { if ((comp[0]) && (comp[1])) { this.document.forms.newaboutsomeone.importdetail.value= - 'About '+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme'; - this.document.forms.newaboutsomeone.submit(); - } else { - alert("Not a valid user:domain"); - } - } else { - alert("Please enter both user and domain in the format user:domain"); - } + '$lt{"p_mab2"}'+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme'; + this.document.forms.newaboutsomeone.submit(); + } else { + alert("$lt{'p_mab_alrt1'}"); } +} else { + alert("$lt{'p_mab_alrt2'}"); +} +} } function makeims() { - var caller = document.forms.ims.folder.value; - var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one"; - newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes"); - newWindow.location.href = newlocation; +var caller = document.forms.ims.folder.value; +var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one"; +newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes"); +newWindow.location.href = newlocation; } - function finishpick() { - var title=this.document.forms.extimport.title.value; - var url=this.document.forms.extimport.url.value; - var form=this.document.forms.extimport.useform.value; - eval - ('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+ - '";this.document.forms.'+form+'.submit();'); +var title=this.document.forms.extimport.title.value; +var url=this.document.forms.extimport.url.value; +var form=this.document.forms.extimport.useform.value; +var residx=this.document.forms.extimport.residx.value; +eval('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+'='+residx+'";this.document.forms.'+form+'.submit();'); } function changename(folderpath,index,oldtitle,container,pagesymb) { - var title=prompt('New Title',oldtitle); - if (title) { - this.document.forms.renameform.title.value=title; - this.document.forms.renameform.cmd.value='rename_'+index; - if (container == 'sequence') { - this.document.forms.renameform.folderpath.value=folderpath; - } - if (container == 'page') { - this.document.forms.renameform.pagepath.value=folderpath; - this.document.forms.renameform.pagesymb.value=pagesymb; +var title=prompt('$lt{"p_chn"}',oldtitle); +if (title) { +this.document.forms.renameform.markcopy.value=-1; +this.document.forms.renameform.title.value=title; +this.document.forms.renameform.cmd.value='rename_'+index; +if (container == 'sequence') { + this.document.forms.renameform.folderpath.value=folderpath; +} +if (container == 'page') { + this.document.forms.renameform.pagepath.value=folderpath; + this.document.forms.renameform.pagesymb.value=pagesymb; +} +this.document.forms.renameform.submit(); +} +} + +function removeres(folderpath,index,oldtitle,container,pagesymb,skip_confirm) { +if (skip_confirm || confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr2a"} "'+oldtitle+'" $lt{"p_rmr2b"}')) { +this.document.forms.renameform.markcopy.value=-1; +this.document.forms.renameform.cmd.value='del_'+index; +if (container == 'sequence') { + this.document.forms.renameform.folderpath.value=folderpath; +} +if (container == 'page') { + this.document.forms.renameform.pagepath.value=folderpath; + this.document.forms.renameform.pagesymb.value=pagesymb; +} +this.document.forms.renameform.submit(); +} +} + +function cutres(folderpath,index,oldtitle,container,pagesymb,folder,skip_confirm) { +if (skip_confirm || confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr2a"} "'+oldtitle+'" $lt{"p_ctr2b"}')) { +this.document.forms.renameform.cmd.value='cut_'+index; +this.document.forms.renameform.markcopy.value=index; +this.document.forms.renameform.copyfolder.value=folder+'.'+container; +if (container == 'sequence') { + this.document.forms.renameform.folderpath.value=folderpath; +} +if (container == 'page') { + this.document.forms.renameform.pagepath.value=folderpath; + this.document.forms.renameform.pagesymb.value=pagesymb; +} +this.document.forms.renameform.submit(); +} +} + +function markcopy(folderpath,index,oldtitle,container,pagesymb,folder) { +this.document.forms.renameform.markcopy.value=index; +this.document.forms.renameform.copyfolder.value=folder+'.'+container; +if (container == 'sequence') { +this.document.forms.renameform.folderpath.value=folderpath; +} +if (container == 'page') { +this.document.forms.renameform.pagepath.value=folderpath; +this.document.forms.renameform.pagesymb.value=pagesymb; +} +this.document.forms.renameform.submit(); +} + +function updatePick(targetform,index,caller) { + var pickitem = document.getElementById('rpick_'+index); + var picknumitem = document.getElementById('rpicknum_'+index); + if (pickitem.checked) { + var picknum=prompt('$lt{"rpck"}',picknumitem.value); + if (picknum == '' || picknum == null) { + if (caller == 'check') { + pickitem.checked=false; + return; + } + } else { + picknum.toString(); + var regexdigit=/^\\d+\$/; + if (regexdigit.test(picknum)) { + picknumitem.value = picknum; + targetform.changeparms.value='randompick'; + targetform.submit(); + } else { + if (caller == 'check') { + pickitem.checked=false; + } + return; + } } - this.document.forms.renameform.submit(); + } else { + picknumitem.value = 0; + targetform.changeparms.value='randompick'; + targetform.submit(); } } -function removeres(folderpath,index,oldtitle,container,pagesymb) { - if (confirm('WARNING: Removing a resource makes associated grades and scores inaccessible!\\nRemove "'+oldtitle+'"?')) { - this.document.forms.renameform.cmd.value='del_'+index; - if (container == 'sequence') { - this.document.forms.renameform.folderpath.value=folderpath; +function unselectInactive(nav) { +currentNav = document.getElementById(nav); +currentLis = currentNav.getElementsByTagName('LI'); +for (i = 0; i < currentLis.length; i++) { + if (currentLis[i].className == 'goback') { + currentLis[i].className = 'goback'; + } else { + if (currentLis[i].className == 'right active' || currentLis[i].className == 'right') { + currentLis[i].className = 'right'; + } else { + currentLis[i].className = 'i'; + } } - if (container == 'page') { - this.document.forms.renameform.pagepath.value=folderpath; - this.document.forms.renameform.pagesymb.value=pagesymb; +} +} + +function hideAll(current, nav, data) { +unselectInactive(nav); +if(current.className == 'right'){ + current.className = 'right active' + }else{ + current.className = 'active'; +} +currentData = document.getElementById(data); +currentDivs = currentData.getElementsByTagName('DIV'); +for (i = 0; i < currentDivs.length; i++) { + if(currentDivs[i].className == 'LC_ContentBox'){ + currentDivs[i].style.display = 'none'; + } +} +} + +function openTabs(pageId) { + tabnav = document.getElementById(pageId).getElementsByTagName('UL'); + if(tabnav.length > 2 ){ + currentNav = document.getElementById(tabnav[1].id); + currentLis = currentNav.getElementsByTagName('LI'); + for(i = 0; i< currentLis.length; i++){ + if(currentLis[i].className == 'active') { + funcString = currentLis[i].onclick.toString(); + tab = funcString.split('"'); + if(tab.length < 2) { + tab = funcString.split("'"); + } + currentData = document.getElementById(tab[1]); + currentData.style.display = 'block'; + } + } + } +} + +function showPage(current, pageId, nav, data) { + hideAll(current, nav, data); + openTabs(pageId); + unselectInactive(nav); + current.className = 'active'; + currentData = document.getElementById(pageId); + currentData.style.display = 'block'; + activeTab = pageId; + if (nav == 'mainnav') { + var storedpath = "$docs_folderpath"; + if (storedpath == '') { + storedpath = "$docs_pagepath"; + } + var storedpage = "$main_container_page"; + var reg = new RegExp("^supplemental"); + if (pageId == 'mainCourseDocuments') { + if (storedpage == 1) { + document.simpleedit.folderpath.value = ''; + document.uploaddocument.folderpath.value = ''; + } else { + if (reg.test(storedpath)) { + document.simpleedit.folderpath.value = '$toplevelmain'; + document.uploaddocument.folderpath.value = '$toplevelmain'; + document.newext.folderpath.value = '$toplevelmain'; + } else { + document.simpleedit.folderpath.value = storedpath; + document.uploaddocument.folderpath.value = storedpath; + document.newext.folderpath.value = storedpath; + } + } + } else { + if (reg.test(storedpath)) { + document.simpleedit.folderpath.value = storedpath; + document.supuploaddocument.folderpath.value = storedpath; + document.supnewext.folderpath.value = storedpath; + } else { + document.simpleedit.folderpath.value = '$toplevelsupp'; + document.supuploaddocument.folderpath.value = '$toplevelsupp'; + document.supnewext.folderpath.value = '$toplevelsupp'; + } + } } - this.document.forms.renameform.submit(); + resize_scrollbox('contentscroll','1','0'); + return false; +} + +function toContents(jumpto) { + var newurl = '$backtourl'; + if (jumpto != '') { + newurl = newurl+'?postdata='+jumpto; +; } + location.href=newurl; } -function cutres(folderpath,index,oldtitle,container,pagesymb) { - if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible!\\nGrades remain inaccessible if resource is pasted into another folder.\\nCut "'+oldtitle+'"?')) { - this.document.forms.renameform.cmd.value='cut_'+index; - this.document.forms.renameform.markcopy.value=index; - if (container == 'sequence') { - this.document.forms.renameform.folderpath.value=folderpath; - } - if (container == 'page') { - this.document.forms.renameform.pagepath.value=folderpath; - this.document.forms.renameform.pagesymb.value=pagesymb; - } - this.document.forms.renameform.submit(); +ENDNEWSCRIPT +} + +sub history_tab_js { + return <<"ENDHIST"; +function toggleHistoryDisp(choice) { + document.docslogform.docslog.value = choice; + document.docslogform.submit(); + return; +} + +ENDHIST +} + +sub inject_data_js { + return <<ENDINJECT; + +function injectData(current, hiddenField, name, value) { + currentElement = document.getElementById(hiddenField); + currentElement.name = name; + currentElement.value = value; + current.submit(); +} + +ENDINJECT +} + +sub dump_switchserver_js { + my @hosts = @_; + my %lt = &Apache::lonlocal::texthash( + dump => 'Dumping to Authoring Space requires switching server.', + swit => 'Switch server?', + duco => 'Dump content to Authoring Space', + yone => 'You need to switch to a server housing an Authoring Space for which you are author or co-author.', + chos => 'Choose server', + ); + my $role = $env{'request.role'}; + my $js = <<"ENDSWJS"; +<script type="text/javascript"> +function write_switchserver() { + var server; + if (document.setserver.posshosts.length > 0) { + for (var i=0; i<document.setserver.posshosts.length; i++) { + if (document.setserver.posshosts[i].checked) { + server = document.setserver.posshosts[i].value; + } + } + opener.document.location.href="/adm/switchserver?otherserver="+server+"&role=$role&origurl=/adm/coursedocs"; } + window.close(); } +</script> + +ENDSWJS -function markcopy(folderpath,index,oldtitle,container,pagesymb) { - this.document.forms.renameform.markcopy.value=index; - if (container == 'sequence') { - this.document.forms.renameform.folderpath.value=folderpath; + my $startpage = &Apache::loncommon::start_page('Choose server',$js, + {'only_body' => 1, + 'js_ready' => 1,}); + my $endpage = &Apache::loncommon::end_page({'js_ready' => 1}); + + my $hostpicker; + my $count = 0; + foreach my $host (sort(@hosts)) { + my $checked; + if ($count == 0) { + $checked = ' checked="checked"'; + } + $hostpicker .= '<label><input type="radio" name="posshosts" value="'. + $host.'"'.$checked.' />'.$host.'</label> '; + $count++; } - if (container == 'page') { - this.document.forms.renameform.pagepath.value=folderpath; - this.document.forms.renameform.pagesymb.value=pagesymb; + + return <<"ENDSWITCHJS"; + +function dump_needs_switchserver(url) { + if (url!='' && url!= null) { + if (confirm("$lt{'dump'}\\n$lt{'swit'}")) { + go(url); + } } - this.document.forms.renameform.submit(); + return; } -ENDNEWSCRIPT +function choose_switchserver_window() { + newWindow = window.open('','ChooseServer','height=400,width=500,scrollbars=yes') + newWindow.document.open(); + newWindow.document.writeln('$startpage'); + newWindow.document.write('<h3>$lt{'duco'}<\\/h3>\\n'+ + '<p>$lt{'yone'}<\\/p>\\n'+ + '<div class="LC_left_float"><fieldset><legend>$lt{'chos'}<\\/legend>\\n'+ + '<form name="setserver" method="post" action="" \\/>\\n'+ + '$hostpicker\\n'+ + '<br \\/><br \\/>\\n'+ + '<input type="button" name="makeswitch" value="$lt{'swit'}" '+ + 'onclick="write_switchserver();" \\/>\\n'+ + '<\\/form><\\/fieldset><\\/div><br clear="all" \\/>\\n'); + newWindow.document.writeln('$endpage'); + newWindow.document.close(); + newWindow.focus(); +} + +ENDSWITCHJS +} + +sub makedocslogform { + my ($formelems,$docslog) = @_; + return <<"LOGSFORM"; + <form action="/adm/coursedocs" method="post" name="docslogform"> + <input type="hidden" name="docslog" value="$docslog" /> + $formelems + </form> +LOGSFORM +} + +sub makesimpleeditform { + my ($formelems) = @_; + return <<"SIMPFORM"; + <form name="simpleedit" method="post" action="/adm/coursedocs"> + <input type="hidden" name="importdetail" value="" /> + $formelems + </form> +SIMPFORM } + 1; __END__ + + +=head1 NAME + +Apache::londocs.pm + +=head1 SYNOPSIS + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + +=head1 SUBROUTINES + +=over + +=item %help=() + +Available help topics + +=item mapread() + +Mapread read maps into LONCAPA::map:: global arrays +@order and @resources, determines status +sets @order - pointer to resources in right order +sets @resources - array with the resources with correct idx + +=item authorhosts() + +Return hash with valid author names + +=item clean() + +=item dumpcourse() + + Actually dump course + +=item group_import() + + Imports the given (name, url) resources into the course + coursenum, coursedom, and folder must precede the list + +=item breadcrumbs() + +=item log_docs() + +=item docs_change_log() + +=item update_paste_buffer() + +=item print_paste_buffer() + +=item do_paste_from_buffer() + +=item update_parameter() + +=item handle_edit_cmd() + +=item editor() + +=item process_file_upload() + +=item process_secondary_uploads() + +=item is_supplemental_title() + +=item entryline() + +=item tiehash() + +=item untiehash() + +=item checkonthis() + +check on this + +=item verifycontent() + +Verify Content + +=item devalidateversioncache() & checkversions() + +Check Versions + +=item mark_hash_old() + +=item is_hash_old() + +=item changewarning() + +=item init_breadcrumbs() + +Breadcrumbs for special functions + +=item create_list_elements() + +=item create_form_ul() + +=item startContentScreen() + +=item endContentScreen() + +=item supplemental_base() + +=item embedded_form_elems() + +=item embedded_destination() + +=item return_to_editor() + +=item decompression_info() + +=item decompression_phase_one() + +=item decompression_phase_two() + +=item remove_archive() + +=item generate_admin_menu() + +=item generate_edit_table() + +=item editing_js() + +=item history_tab_js() + +=item inject_data_js() + +=item dump_switchserver_js() + +=item resize_scrollbox_js() + +=item makedocslogform() + +=item makesimpleeditform() + +=back + +=cut