--- loncom/interface/londocs.pm 2011/07/04 16:47:03 1.455 +++ loncom/interface/londocs.pm 2012/04/08 22:34:58 1.481 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.455 2011/07/04 16:47:03 raeburn Exp $ +# $Id: londocs.pm,v 1.481 2012/04/08 22:34:58 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,8 +26,6 @@ # http://www.lon-capa.org/ # - - package Apache::londocs; use strict; @@ -41,6 +39,7 @@ use Apache::lonratedt(); use Apache::lonxml; use Apache::lonclonecourse; use Apache::lonnavmaps; +use Apache::lonnavdisplay(); use HTML::Entities; use GDBM_File; use Apache::lonlocal; @@ -176,7 +175,7 @@ sub dumpcourse { $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++) { @@ -264,807 +263,12 @@ sub dumpcourse { } } - - sub exportbutton { my $crstype = &Apache::loncommon::course_type(); return "<a class='LC_menubuttons_link' href='javascript:injectData(document.courseverify, \"dummy\", \"exportcourse\", \"".&mt('IMS Export')."\")'>".&mt('IMS Export')."</a>". &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'<br />'; } - - -sub exportcourse { - my $r=shift; - my $crstype = &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 $numprobs = 0; - my $navmap = Apache::lonnavmaps::navmap->new(); - if (!defined($navmap)) { - $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package'). - '<h2>'.&mt('IMS Export Failed').'</h2>'. - '<div class="LC_error">'); - if ($crstype eq 'Community') { - $r->print(&mt('Unable to retrieve information about community contents')); - } else { - $r->print(&mt('Unable to retrieve information about course contents')); - } - $r->print('</div><a href="/adm/coursedocs">'); - if ($crstype eq 'Community') { - $r->print(&mt('Return to Community Editor')); - } else { - $r->print(&mt('Return to Course Editor')); - } - $r->print('</a>'); - &Apache::lonnet::logthis('IMS export failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); - return; - } - my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef); - my $curRes; - my $outcome; - - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['finishexport']); - if ($env{'form.finishexport'}) { - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['archive','discussion']); - - my $format = $env{'form.format'}; - my @exportitems = &Apache::loncommon::get_env_multiple('form.archive'); - my @discussions = &Apache::loncommon::get_env_multiple('form.discussion'); - if (@exportitems == 0 && @discussions == 0) { - $outcome = - '<p class="LC_warning">' - .&mt('As you did not select any content items or discussions' - .' for export, an IMS package has not been created.') - .'</p>' - .'<p>' - .&mt('Please [_1]go back[_2] to select either content items' - .' or discussions for export.' - ,'<a href="javascript:history.go(-1)">' - ,'</a>') - .'</p>'; - } else { - my $now = time; - my %symbs; - my $manifestok = 0; - my $imsresources; - my $tempexport; - my $copyresult; - my $testbank; - my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport,$format,\$testbank); - if ($manifestok) { - &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest,$format,$testbank); - 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 .= '<p>' - .&mt('[_1]Your IMS package[_2] is ready for download.' - ,'<a href="'.$imszipfile.'">','</a>') - .'</p>'; - if ($copyresult) { - $outcome .= '<p class="LC_error">' - .&mt('The following errors occurred during export - [_1]' - ,$copyresult) - .'</p>'; - } - } else { - $outcome = '<p class="LC_error">' - .&mt('Unfortunately you will not be able to retrieve' - .' an IMS archive of your course at this time,' - .' because there was a problem creating a' - .' manifest file.') - .'</p>' - .'<p><a href="javascript:history.go(-1)">' - .&mt('Go Back') - .'</a></p>'; - } - } - $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package')); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export')); - $r->print($outcome); - $r->print(&Apache::loncommon::end_page()); - } else { - my $display='<form name="exportdoc" action="" method="post">'."\n". - '<p>'. - &mt('Choose which items you wish to export from your '.$crstype.'.'). - '</p>'. - '<div class="LC_columnSection"><fieldset>'. - '<legend>'.&mt('Content items').'</legend>'. - '<input type="button" value="'.&mt('check all').'" '. - 'onclick="javascript:checkAll(document.exportdoc.archive)" />'. - ' <input type="button" value="'.&mt('uncheck all').'"'. - ' onclick="javascript:uncheckAll(document.exportdoc.archive)" /></fieldset>'; - if ($numdisc > 0) { - $display .= '<fieldset>'. - '<legend>'.&mt('Discussion posts').'</legend>'. - '<input type="button" value="'.&mt('check all').'"'. - ' onclick="javascript:checkAll(document.exportdoc.discussion)" />'. - ' <input type="button" value="'.&mt('uncheck all').'"'. - ' onclick="javascript:uncheckAll(document.exportdoc.discussion)" />'. - '</fieldset>'; - } - $display .= '</div>'; - my $curRes; - my $depth = 0; - my $count = 0; - my $boards = 0; - my $startcount = 5; - my %parent = (); - my %children = (); - my $lastcontainer = $startcount; - $display .= &Apache::loncommon::start_data_table() - .&Apache::loncommon::start_data_table_header_row() - .'<th>'.&mt('Export content item?').'</th>'; - if ($numdisc > 0) { - $display .= '<th>'.&mt('Export discussion posts?').'</th>'; - } - $display .= &Apache::loncommon::end_data_table_header_row(); - 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/($match_domain)/($match_username)/(\d+)/bulletinboard$|) { - unless ($ressymb =~ m|adm/wrapper/adm|) { - $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard'; - } - } - my $currelem = $count+$boards+$startcount; - $display .= &Apache::loncommon::start_data_table_row() - .'<td>'."\n" - .'<input type="checkbox" name="archive" value="'.$count.'" '; - if (($curRes->is_sequence()) || ($curRes->is_page())) { - $lastcontainer = $currelem; - $display .= 'onclick="javascript:propagateCheck('."'$currelem'".')"'; - } elsif ($curRes->is_problem()) { - $numprobs ++; - } - $display .= ' />'."\n"; - for (my $i=0; $i<$depth; $i++) { - $display .= ('<img src="/adm/lonIcons/whitespace1.gif" class="LC_docs_spacer" alt="" />' x2)."\n"; - } - if ($curRes->is_sequence()) { - $display .= '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" /> '."\n"; - } elsif ($curRes->is_page()) { - $display .= '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" /> '."\n"; - } - $children{$parent{$depth}} .= $currelem.':'; - $display .= ' '.$curRes->title().'</td>'."\n"; - - # Existing discussion posts? - if ($discussiontime{$ressymb} > 0) { - $boards ++; - $display .= '<td align="right">' - .'<input type="checkbox" name="discussion" value="'.$count.'" />' - .'</td>'."\n"; - } elsif ($numdisc > 0) { - $display .= '<td> </td>'."\n"; - } - $display .= &Apache::loncommon::end_data_table_row(); - } - } - $display .= &Apache::loncommon::end_data_table(); - my $scripttag = qq| -<script type="text/javascript"> -// <![CDATA[ -function checkAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = true ; - } - } else { - field.checked = true - } -} - -function uncheckAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = false ; - } - } else { - field.checked = false ; - } -} - -function propagateCheck(item) { - if (document.exportdoc.elements[item].checked == true) { - containerCheck(item) - } -} - -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 - } - |; - - 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"; - } - } - - $scripttag .= qq| - if (parents[item].length > 0) { - for (var j=0; j<parents[item].length; j++) { - containerCheck(parents[item][j]) - } - } -} -// ]]> -</script> - |; - $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package', - $scripttag)); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export')); - if ($numprobs > 0) { - $display .= '<p><span class="LC_nobreak">'. - &mt('Export format for LON-CAPA problems:'). - '<label><input type="radio" name="format" value="xml" checked="checked" />'. - ' '.&mt('XML').'</label>'.(' ' x3). - '<label><input type="radio" name="format" value="html" />'. - ' '.&mt('HTML').'</label>'.(' ' x3). - '<label><input type="radio" name="format" value="plaintext" />'. - ' '.&mt('Text').'</label></span></p>'; - } - $r->print($display. - '<p><input type="hidden" name="finishexport" value="1" />'. - '<input type="submit" name="exportcourse" value="'. - &mt('Export').'" /></p></form>'); - } -} - -sub create_ims_store { - my ($now,$manifestok,$outcome,$tempexport,$format,$testbank) = @_; - $$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>'; - if ($format eq 'plaintext') { - my $testbankfilename = $$tempexport.'/testbank.txt'; - $$testbank = Apache::File->new('>'.$testbankfilename); - } - } else { - $$outcome .= 'An error occurred opening the IMS manifest file.<br />' -; - } - return $ims_manifest; -} - -sub build_package { - my ($now,$navmap,$exportitems,$discussions,$outcome,$tempexport,$copyresult, - $ims_manifest,$format,$testbank) = @_; -# 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 ++; - } - if ($curRes == $it->BEGIN_MAP()) { - $depth++; - $parent{$depth} = $lastcontainer; - } - if ($curRes == $it->END_MAP()) { - $depth--; - $lastcontainer = $parent{$depth}; - } - if (ref($curRes)) { - if ($curRes->is_sequence() || $curRes->is_page()) { - $lastcontainer = $count; - } - if (grep(/^$count$/,@$exportitems)) { - &get_dependencies($exportitems,\%parent,$depth,\@dependencies); - } - } - } -# 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; - my $currdirpath = 'Top'; - while ($curRes = $it->next()) { - if ($curRes == $it->BEGIN_MAP()) { - $prevdepth = $depth; - $depth++; - } - if ($curRes == $it->END_MAP()) { - $prevdepth = $depth; - $depth--; - } - - 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 --; - } - } - $prevdepth = $depth; - - my $itementry = - '<item identifier="ITEM-'.$env{'request.course.id'}.'-'.$count. - '" isvisible="'.$isvisible.'" '.$resourceref.'>'. - '<title>'.$curRes->title().'</title>'; - print $ims_manifest "\n".$itementry; - - if ($curRes->is_sequence()) { - $currdirpath = 'Top'; - my $pcslist = $curRes->map_hierarchy(); - if ($pcslist ne '') { - foreach my $pc (split(/,/,$pcslist)) { - my $res = $navmap->getByMapPc($pc); - if (ref($res)) { - my $encloser = $res->title(); - if ($encloser) { - if ($currdirpath) { - $currdirpath .= ' -> '; - } - $currdirpath .= $encloser; - } - } - } - } - } else { - my $content_file; - my @hrefs = (); - &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport,$format,$currdirpath,$testbank); - 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 my $item (@hrefs) { - $imsresources .= - ' <file href="'.$item.'" />'."\n"; - } - if (grep(/^$count$/,@$discussions)) { - my $ressymb = $symb; - my $mode; - if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\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"; - } - } - $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); - } - } - } -} - -sub process_content { - my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport,$format,$currdirpath,$testbank) = @_; - 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/($match_domain)/($match_username)/(\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 (($format eq 'html') || ($format eq 'plaintext')) { - my $title = $curRes->title; - $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,$format,$currdirpath,$title,$testbank); - } elsif ($format eq 'xml') { - 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"; - } - } - } - if ($message) { - $$copyresult .= $message."\n"; - } -} - -sub replicate_content { - my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller,$currdirpath, - $title,$testbank) = @_; - my ($map,$ind,$url); - if ($caller eq 'templateupload') { - $url = $symb; - $url =~ s#//#/#g; - } else { - ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); - } - 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'; - } - } 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'); - } - } else { - $$message = 'Could not render '.$url.' server message - '.$rtncode."<br />\n"; - } - } elsif (($caller eq 'noedit') || ($caller eq 'html') || - ($caller eq 'plaintext')) { -# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this. - my %form = ( - grade_symb => $symb, - grade_courseid => $cdom.'_'.$cnum, - grade_domain => $env{'user.domain'}, - grade_username => $env{'user.name'}, - grade_imsexport => 1, - ); - my $feedurl=&Apache::lonnet::clutter($url); - my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form); - if (ref($response)) { - if ($response->is_success) { - $content = $userview; - $content =~ s/\Qonchange="javascript:setSubmittedPart('\E[^\']+\Q');"\E//g; - $content =~ s/^\s*[\n\r]+$//; - if ($caller eq 'plaintext') { - my @lines = split(/[\n\r]+/,$content); - my @tosave; - my $foilcounter = 0; - my @alphabet = ('a'..'z'); - my $mc_answer; - foreach my $line (@lines) { - next if ($line =~ /^\s*$/); - if ($line =~ m{(|\Q<\label>\E)\Q<br />Incorrect:<label>\E}) { - $foilcounter ++; - } elsif ($line =~ m{(|\Q</label>\E)\Q<br />Correct:<b><label>\E}) { - $foilcounter ++; - $mc_answer = $alphabet[$foilcounter]; - } elsif ($line !~ m{\Q</label>\E(|\Q</b>\E)\Q<br />\E}) { - $line =~ s/^(\s+|\s+)$//g; - $line =~ s{^\Q<b>\E([^<]+)\Q</b>\E$}{1}; - push(@tosave,$line); - } - $content = join("\t",@tosave); - if ($mc_answer) { - $content .= "\t".$mc_answer."\n"; - } - } - if (@tosave) { - my $qtype; - if ($mc_answer) { - $qtype = 'MC'; - } - $content = $currdirpath."\t".$title."\t$qtype\t".join("\t",@tosave); - if ($mc_answer) { - $content .= "\t".$mc_answer; - } - $content .= "\n"; - } - } else { - $content = '<html><body>'.$content.'</body></html>'; - } - if (($caller eq 'plaintext') && ($testbank)) { - print $testbank $content; - } - } else { - $content = 'Not the owner of this resource'; - } - } else { - $content = 'Not the owner of this resource'; - } - $repstatus = 'ok'; - } - if ($repstatus eq 'ok') { - print $copiedfile $content; - } - 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; -} - -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,\%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 - } - } - 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'; - } - } 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; - } - } - } else { - $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode."<br />\n"; - } - } - 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); - } - if ($content_type eq 'external') { - return 'resources/'.$count.'/'.$content_type.'.html'; - } else { - return 'resources/'.$count.'/'.$content_type.'.xml'; - } - } - } -} - - sub group_import { my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_; @@ -1125,37 +329,33 @@ sub breadcrumbs { my $isencrypted=0; my $ishidden=0; my $is_random_order=0; - if (!$allowed) { - my $description = $env{'course.'.$env{'request.course.id'}.'.description'}; - &Apache::lonhtmlcommon::add_breadcrumb( - {'href' => '/adm/menu', - 'title'=> 'Go to main menu', - 'text' => $description, - }); - $plain .= $description.' >'; - } while (@folders) { my $folder=shift(@folders); my $foldername=shift(@folders); if ($folderpath) {$folderpath.='&';} $folderpath.=$folder.'&'.$foldername; - my $url='/adm/coursedocs?folderpath='. - &escape($folderpath); - my $name=&unescape($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.' Documents'); - } - &Apache::lonhtmlcommon::add_breadcrumb( + $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, @@ -1165,7 +365,8 @@ sub breadcrumbs { } $plain=~s/\>\;\s*$//; return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp', - undef, undef, 1 ),$randompick,$ishidden,$isencrypted,$plain,$is_random_order); + undef, undef, 1 ),$randompick,$ishidden, + $isencrypted,$plain,$is_random_order); } sub log_docs { @@ -1567,7 +768,6 @@ sub update_parameter { sub handle_edit_cmd { my ($coursenum,$coursedom) =@_; - my ($cmd,$idx)=split('_',$env{'form.cmd'}); my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]; @@ -1575,7 +775,7 @@ sub handle_edit_cmd { if ($cmd eq 'del') { if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && - ($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) { + ($url!~/$LONCAPA::assess_page_seq_re/)) { &Apache::lonnet::removeuploadedurl($url); } else { &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]); @@ -1611,7 +811,8 @@ sub handle_edit_cmd { } sub editor { - my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype)=@_; + my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype, + $supplementalflag,$orderhash,$iconpath)=@_; my $container= ($env{'form.pagepath'}) ? 'page' : 'sequence'; @@ -1627,8 +828,10 @@ sub editor { } my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = - &breadcrumbs($allowed,$crstype); - $r->print($breadcrumbtrail); + &breadcrumbs($allowed,$crstype); + $r->print($breadcrumbtrail); + + my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; unless ($allowed) { $randompick = -1; @@ -1740,7 +943,7 @@ sub editor { $r->print('</div>'); } - my $output; + my ($to_show,$output); &Apache::loncommon::start_data_table_count(); #setup a row counter foreach my $res (@LONCAPA::map::order) { @@ -1757,30 +960,51 @@ sub editor { &Apache::loncommon::end_data_table_count(); if ($shown) { - $r->print(&Apache::loncommon::start_scrollbox('900px','880px','400px') - .&Apache::loncommon::start_data_table()); + $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll') + .&Apache::loncommon::start_data_table(undef,'contentlist'); if ($allowed) { - $r->print(&Apache::loncommon::start_data_table_header_row() + $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>'); + .'<th colspan="2">'.&mt('Document').'</th>'; if ($folder !~ /^supplemental/) { - $r->print('<th colspan="4">'.&mt('Settings').'</th>'); + $to_show .= '<th colspan="4">'.&mt('Settings').'</th>'; } - $r->print(&Apache::loncommon::end_data_table_header_row()); + $to_show .= &Apache::loncommon::end_data_table_header_row(); } - $r->print($output + $to_show .= $output.' ' .&Apache::loncommon::end_data_table() - .&Apache::loncommon::end_scrollbox() - ); + .'<br style="line-height:2px;" />' + .&Apache::loncommon::end_scrollbox(); } else { - $r->print('<p class="LC_info">' + $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll') + .'<div class="LC_info" id="contentlist">' .&mt('Currently no documents.') - .'</p>' - ); + .'</div>' + .&Apache::loncommon::end_scrollbox(); + } + my $tid = 1; + if ($supplementalflag) { + $tid = 2; } if ($allowed) { + $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,$jumpto)); &print_paste_buffer($r,$container); + } 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( + &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; } @@ -1810,7 +1034,7 @@ sub process_file_upload { $LONCAPA::map::resources[1]=''; } if ($fatal) { - $$upload_output = '<p><span class="LC_error">'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'</span></p>'; + $$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/'; @@ -1836,7 +1060,7 @@ sub process_file_upload { } else { my ($filename) = ($env{'form.uploaddoc.filename'} =~ m{([^/]+)$}); - $$upload_output = '<p><span class="LC_error">'.&mt('Unable to save file [_1].','<span class="LC_filename">'.$filename.'</span>').'</span></p>'; + $$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'; @@ -1855,7 +1079,7 @@ sub process_file_upload { ($errtext,$fatal)=&storemap($coursenum,$coursedom, $folder.'.'.$container); if ($fatal) { - $$upload_output = '<p><span class="LC_error">'.$errtext.'</span></p>'; + $$upload_output = '<div class="LC_error" id="uploadfileresult">'.$errtext.'</div>'; return; } else { if ($parseaction eq 'parse' && $mimetype eq 'text/html') { @@ -1882,12 +1106,60 @@ sub process_file_upload { } else { $$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 $nextphase; } +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]); + } + } + return @dir_lines; +} + sub is_supplemental_title { my ($title) = @_; return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/); @@ -1938,7 +1210,7 @@ sub entryline { $renametitle=~s/\"\;/\\\"/g; $renametitle=~s/ /%20/g; my $line=&Apache::loncommon::start_data_table_row(); - my ($form_start,$form_end); + my ($form_start,$form_end,$form_common); # Edit commands my ($container, $type, $esc_path, $path, $symb); if ($env{'form.folderpath'}) { @@ -1958,8 +1230,7 @@ sub entryline { if ($allowed) { my $incindex=$index+1; my $selectbox=''; - if (($folder!~/^supplemental/) && - ($#LONCAPA::map::order>0) && + if (($#LONCAPA::map::order>0) && ((split(/\:/, $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1] ne '') && @@ -2030,8 +1301,10 @@ ENDCOPY <a href='javascript:cutres("$esc_path","$index","$renametitle","$container","$symb","$folder",$skip_confirm);' class="LC_docs_cut">$lt{'ct'}</a> ENDCUT } - $form_start = (<<END); - <form action="/adm/coursedocs" method="post"> + $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" /> @@ -2053,6 +1326,7 @@ END </td> <td> $form_start + $form_common $selectbox $form_end </td> @@ -2075,18 +1349,23 @@ END my $pagearg; my $pagefile; if ($uploaded) { - if ($extension eq 'sequence') { - $icon=$iconpath.'/navmap.folder.closed.gif'; - $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/; - $url='/adm/coursedocs?'; - $folderarg=$1; - $isfolder=1; - } elsif ($extension eq 'page') { - $icon=$iconpath.'/page.gif'; - $url=~/\Q$coursenum\E\/([\/\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); } @@ -2131,7 +1410,7 @@ END $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); } } - my ($parameterset,$rand_order_text) = (' ', ' '); + my ($rand_pick_text,$rand_order_text); if ($isfolder || $extension eq 'sequence') { my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; @@ -2147,16 +1426,27 @@ END .':'.((&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.changeparms.value='."'randompick'".';this.form.submit()" name="randompick_'.$orderidx.'" value="'. - (&LONCAPA::map::getparameter($orderidx, - 'parameter_randompick'))[0]. - '" />'. -'<a href="javascript:void(0)">'.&mt('Save').'</a></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 =' -<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>'; + $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); @@ -2188,13 +1478,27 @@ END } else { $reinit = &mt('(re-initialize course to access)'); } - $line.=' - <td> - '.($url?'<a href="'.$url.'">':'').'<img src="'.$icon.'" alt="" class="LC_icon" />'.($url?'</a>':'').' - </td> - <td> - '.($url?"<a href=\"$url\">":'').$title.($url?'</a>':' <span class="LC_docs_reinit_warn">'.$reinit.'</span>').$external." - </td>"; + $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.=$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', @@ -2206,16 +1510,17 @@ END $line.=(<<ENDPARMS); <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 - </td> - <td class="LC_docs_entry_parameter"> + <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">$form_start $rand_order_text $form_end</td> - <td class="LC_docs_entry_parameter">$form_start $parameterset $form_end</td> + <td class="LC_docs_entry_parameter">$rand_pick_text<br /> + $rand_order_text</td> ENDPARMS } $line.=&Apache::loncommon::end_data_table_row(); @@ -2454,9 +1759,11 @@ sub checkversions { 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 Saved').'</h1>'); + $r->print(&Apache::loncommon::confirmwrapper( + &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved')))); } else { - $r->print('<h1><span class="LC_error">'.&mt('An Error Occured while Attempting to Save your Version Settings').'</span></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(); } @@ -2522,12 +1829,19 @@ sub checkversions { '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', + 'act' => 'Actions'); $r->print(<<ENDHEADERS); <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_columnSection"> +<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> <select name="timerange"> <option value='all' $allsel>$lt{'al'}</option> <option value="-1" $startsel>$lt{'st'}</option> @@ -2536,47 +1850,49 @@ 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'}" /> +<h2>$header</h2> +<input type="submit" name="setversions" value="$lt{'save'}" /> <table border="0"> ENDHEADERS + #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($key); - $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'}.'"><span class="LC_nobreak">Most Recent: '. - '<font size="+1">'.$currentversion.'</font>'. - '</span></td>'. - '<td title="'.$lt{'ve'}.'"><span class="LC_nobreak">In '.$crstype.': '. - '<font size="+1">'); + $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></span></td><td title="'.$lt{'vu'}.'">'. - '<span class="LC_nobreak">Use: '); + $r->print('</td><td title="'.$lt{'vu'}.'">'); # Set version $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, 'set_version_'.$linkurl, @@ -2585,7 +1901,6 @@ ENDHEADERS '' => '', 'mostrecent' => &mt('most recent'), map {$_,$_} (1..$currentversion)})); - $r->print('</span></td></tr><tr><td></td>'); my $lastold=1; for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { my $url=$root.'.'.$prevvers.'.'.$extension; @@ -2599,13 +1914,13 @@ ENDHEADERS # 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; @@ -2620,25 +1935,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('</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('<p class="LC_success">'.&mt('Done').'</p>'); + $r->print('</td>'.&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(). + '<input type="submit" name="setversions" value="'.$lt{'save'}.'" />'); &untiehash(); } @@ -2739,27 +2054,21 @@ sub create_form_ul { sub startContentScreen { my ($r,$mode)=@_; $r->print('<ul class="LC_TabContentBigger" id="mainnav">'); - $r->print('<li'.(($mode eq 'navmaps')?' class="active"':'').'><a href="/adm/navmaps"><b> '.&mt('Content Overview').' </b></a></li>'); - - my $active = ''; -# does this user have privileges to modify docs? - my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'}); - - my $onclick; - my $href; - - if ($allowed) { + if (($mode eq 'navmaps') || ($mode eq 'supplemental')) { + $r->print('<li'.(($mode eq 'navmaps')?' class="active"':'').'><a href="/adm/navmaps"><b> '.&mt('Content Overview').' </b></a></li>'."\n"); + $r->print('<li'.(($mode eq 'coursesearch')?' class="active"':'').'><a href="/adm/searchcourse"><b> '.&mt('Content Search').' </b></a></li>'."\n"); + $r->print('<li'.(($mode eq 'courseindex')?' class="active"':'').'><a href="/adm/indexcourse"><b> '.&mt('Content Index').' </b></a></li>'."\n"); + $r->print('<li '.(($mode eq 'suppdocs')?' class="active"':'').'><a href="/adm/supplemental"><b>'.&mt('Supplemental Content').'</b></a></li>'); + } else { $r->print('<li '.(($mode eq 'docs')?' class="active"':''). - '><a href="/adm/coursedocs?forcestandard=1"><b> '.&mt('Content Editor').' </b></a></li>'); - } - $r->print('<li'.(($mode eq 'coursesearch')?' class="active"':'').'><a href="/adm/searchcourse"><b> '.&mt('Content Search').' </b></a></li>'); - $r->print('<li'.(($mode eq 'courseindex')?' class="active"':'').'><a href="/adm/indexcourse"><b> '.&mt('Content Index').' </b></a></li>'); - $r->print('<li '.(($mode eq 'supdocs')?' class="active"':''). - '><a href="/adm/coursedocs?forcesupplement=1"><b>'.&mt('Supplemental Documents').'</b></a></li>'); - $r->print('</ul>'); - $r->print('<div class="LC_Box" style="clear:both;margin:0;">' - .'<div id="maincoursedoc" style="margin:0 0;padding:0 0;">'); - $r->print('<div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">'); + ' id="tabbededitor"><a href="/adm/coursedocs?forcestandard=1"><b> '.&mt('Content Editor').' </b></a></li>'); + $r->print('<li '.(($mode eq 'suppdocs')?' class="active"':''). + '><a href="/adm/coursedocs?forcesupplement=1"><b>'.&mt('Supplemental Content Editor').'</b></a></li>'); + } + $r->print("\n".'</ul>'."\n"); + $r->print('<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;">'); } # @@ -2772,7 +2081,7 @@ sub endContentScreen { } sub supplemental_base { - return 'supplemental&'.&escape(&mt('Supplemental '.&Apache::loncommon::course_type().' Documents')); + return 'supplemental&'.&escape(&mt('Supplemental '.&Apache::loncommon::course_type().' Content')); } sub handler { @@ -2806,8 +2115,14 @@ sub handler { $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'}) { &init_breadcrumbs('verify','Verify Content'); &verifycontent($r); @@ -2825,7 +2140,7 @@ sub handler { &dumpcourse($r); } elsif ($allowed && $env{'form.exportcourse'}) { &init_breadcrumbs('exportcourse','IMS Export'); - &exportcourse($r); + &Apache::imsexport::exportcourse($r); } else { # # Done catching special calls @@ -2834,7 +2149,8 @@ sub handler { # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['folderpath','pagepath', - 'pagesymb','forcesupplement','forcestandard']); + 'pagesymb','forcesupplement','forcestandard', + '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 @@ -2857,15 +2173,91 @@ sub handler { my $script=''; my $showdoc=0; + my $addentries = {}; + my $container; my $containertag; my $uploadtag; +# 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, @@ -2897,7 +2289,7 @@ sub handler { } else { $env{'form.folderpath'}='default'; } - } + } # Store this &Apache::loncommon::store_course_settings($stored_folderpath, @@ -2908,11 +2300,13 @@ sub handler { 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 = @@ -2957,7 +2351,22 @@ sub handler { $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/"); if ($allowed) { - $script .= &editing_js($udom,$uname); + 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). + &resize_contentdiv_js($tabidstr); + $addentries = { + onload => "javascript:resize_contentdiv('contentscroll','1','1');", + }; } # -------------------------------------------------------------------- Body tag $script = '<script type="text/javascript">'."\n" @@ -2973,7 +2382,9 @@ sub handler { href=>"/adm/coursedocs",text=>"$crstype Contents"}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, - {'force_register' => $showdoc,}) + {'force_register' => $showdoc, + 'add_entries' => $addentries, + }) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( 'Editing the Table of Contents for your '.$crstype, @@ -3025,6 +2436,14 @@ sub handler { $docuname,$docudom,undef, $dir_root). &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()); } } @@ -3082,22 +2501,22 @@ FIUP </label> CHBO - my $fileuploada = "<input type='submit' value='".$lt{'upld'}."' /> $help{'Uploading_From_Harddrive'}"; + 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="80" name="comment" /> + <input type="text" size="60" name="comment" /> $uploadtag <input type="hidden" name="cmd" value="upload_default" /> <br /> - <span class="LC_nobreak"> + <span class="LC_nobreak" style="float:left"> $checkbox </span> FUFORM - $fileuploadform .= &create_form_ul(&Apache::lonhtmlcommon::htmltag('li',$fileuploada,{class => 'LC_menubuttons_inline_text'})).'</form>'; + $fileuploadform .= $fileuploada.'</form>'; my $simpleeditdefaultform=(<<SEDFFORM); <form action="/adm/coursedocs" method="post" name="simpleeditdefault"> @@ -3110,15 +2529,13 @@ SEDFFORM ); $simpleeditdefaultform .= &create_form_ul(&create_list_elements(@simpleeditdefaultforma)); $simpleeditdefaultform .=(<<SEDFFORM); - <hr /> - <p> + <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"><input type="button" + <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> - </p> </form> SEDFFORM @@ -3156,8 +2573,12 @@ HIDDENFORM } # Generate the tabs - &startContentScreen($r,($supplementalflag?'supdocs':'docs')); - + my $mode; + if (($supplementalflag) && (!$allowed)) { + &Apache::lonnavdisplay::startContentScreen($r,'supplemental'); + } else { + &startContentScreen($r,($supplementalflag?'suppdocs':'docs')); + } # @@ -3365,7 +2786,7 @@ NGFFORM 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/>' . $fileuploadform; + $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}, @@ -3406,7 +2827,8 @@ unless ($env{'form.pagepath'}) { $hadchanges=0; unless ($supplementalflag) { - my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,\%orderhash,$iconpath); if ($error) { $r->print('<p><span class="LC_error">'.$error.'</span></p>'); } @@ -3415,10 +2837,8 @@ unless ($env{'form.pagepath'}) { } &changewarning($r,''); - $r->print(&generate_edit_table('1',\%orderhash)); } - - } + } # Supplemental documents start here @@ -3512,21 +2932,22 @@ 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/>' . $supupdocform; +$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 Documents',$supupdocform], 'ff' => ['Special Documents',&create_form_ul(&create_list_elements(@specialdocs))] ); if ($supplementalflag) { - my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,\%suporderhash,$iconpath); if ($error) { $r->print('<p><span class="LC_error">'.$error.'</span></p>'); } - $r->print(&generate_edit_table('2',\%suporderhash)); } } elsif ($supplementalflag) { - my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype); + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,'',$iconpath); if ($error) { $r->print('<p><span class="LC_error">'.$error.'</span></p>'); } @@ -3593,6 +3014,117 @@ sub 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/docs/\E(?:default|supplemental|\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_options { my ($help_ref,$env_ref) = @_; my %lt=&Apache::lonlocal::texthash( @@ -3629,7 +3161,7 @@ sub generate_admin_options { sub generate_edit_table { - my ($tid,$orderhash_ref) = @_; + my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto) = @_; return unless(ref($orderhash_ref) eq 'HASH'); my %orderhash = %{$orderhash_ref}; my $form; @@ -3638,31 +3170,41 @@ sub generate_edit_table { if($env{'form.active'} ne ''){ $activetab = $env{'form.active'}; } - $form = '<div class="LC_Box" style="margin-right:0">'; - $form .= '<ul id="navigation'.$tid.'" class="LC_TabContent">'; - foreach my $name (sort(keys(%orderhash))){ + 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">'. + '<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>'; + 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 '.$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>'; } else { - $form .= '<li '.$active.'>'.${$orderhash{$name}}[1].'</li>'; + $form .= '<li '.$active.' style="float:right">'.${$orderhash{$name}}[1].'</li>'; } } $form .= '</ul>'; - $form .= '<div id="content'.$tid.'" style="padding: 0 0; margin: 0 0; clear: both;">'; + $form .= '<div id="content'.$tid.'" style="padding: 0 0; margin: 0 0; overflow: hidden; clear:right">'; + + if ($to_show ne '') { + $form .= '<div style="padding:0;margin:0;float:left">'.$to_show.'</div>'; + } foreach my $field (keys(%orderhash)){ if($field ne '00'){ if($activetab eq '' || $activetab ne $field){ - $active = 'style="display: none;"'; + $active = 'style="display: none;float:left"'; }elsif($activetab eq $field){ - $active = 'style="display:block;"'; + $active = 'style="display:block;float:left"'; } $form .= '<div id="'.$field.$tid.'"' .' class="LC_ContentBox" '.$active.'>'.${$orderhash{$field}}[1] @@ -3675,7 +3217,7 @@ sub generate_edit_table { } sub editing_js { - my ($udom,$uname) = @_; + my ($udom,$uname,$supplementalflag) = @_; my $now = time(); my %lt = &Apache::lonlocal::texthash( p_mnf => 'Name of New Folder', @@ -3698,7 +3240,8 @@ sub editing_js { 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]' + p_ctr2b => '?[_98]', + rpck => 'Enter number to pick (e.g., 3)', ); my $crstype = &Apache::loncommon::course_type(); @@ -3713,6 +3256,11 @@ sub editing_js { 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('$lt{"p_mnf"}','$lt{"t_mnf"}'); @@ -3817,7 +3365,6 @@ newWindow = window.open("","IMSimport"," newWindow.location.href = newlocation; } - function finishpick() { var title=this.document.forms.extimport.title.value; var url=this.document.forms.extimport.url.value; @@ -3887,15 +3434,50 @@ this.document.forms.renameform.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; + } + } + } else { + picknumitem.value = 0; + targetform.changeparms.value='randompick'; + targetform.submit(); + } +} + function unselectInactive(nav) { currentNav = document.getElementById(nav); currentLis = currentNav.getElementsByTagName('LI'); for (i = 0; i < currentLis.length; i++) { - if(currentLis[i].className == 'right active' || currentLis[i].className == 'right'){ + 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{ + } else { currentLis[i].className = 'i'; - } + } + } } } @@ -3941,6 +3523,7 @@ function showPage(current, pageId, nav, current.className = 'active'; currentData = document.getElementById(pageId); currentData.style.display = 'block'; + activeTab = pageId; if (nav == 'mainnav') { var storedpath = "$docs_folderpath"; if (storedpath == '') { @@ -3975,6 +3558,7 @@ function showPage(current, pageId, nav, } } } + resize_contentdiv('contentscroll','1','0'); return false; } @@ -3985,8 +3569,208 @@ function injectData(current, hiddenField current.submit(); } +function toContents(jumpto) { + var newurl = '$backtourl'; + if (jumpto != '') { + newurl = newurl+'?postdata='+jumpto; +; + } + location.href=newurl; +} + ENDNEWSCRIPT } + +sub resize_contentdiv_js { + my ($tabidstr) = @_; + my $viewport_js = &Apache::loncommon::viewport_geometry_js(); + return <<ENDRESIZESCRIPT; + +window.onresize=resizeContentEditor; + +var activeTab; + +$viewport_js + +function resize_contentdiv(scrollboxname,chkw,chkh) { + var scrollboxid = 'div_'+scrollboxname; + var scrolltableid = 'table_'+scrollboxname; + var scrollbox; + var scrolltable; + + if (document.getElementById("contenteditor") == null) { + return; + } + + if (document.getElementById(scrollboxid) == null) { + return; + } else { + scrollbox = document.getElementById(scrollboxid); + } + + if (document.getElementById(scrolltableid) == null) { + return; + } else { + scrolltable = document.getElementById(scrolltableid); + } + + init_geometry(); + var vph = Geometry.getViewportHeight(); + var vpw = Geometry.getViewportWidth(); + + var alltabs = ['$tabidstr']; + var listwchange; + if (chkw == 1) { + var contenteditorw = document.getElementById("contenteditor").offsetWidth; + var contentlistw; + var contentlistid = document.getElementById("contentlist"); + if (contentlistid != null) { + contentlistw = document.getElementById("contentlist").offsetWidth; + } + var contentlistwstart = contentlistw; + + var scrollboxw = scrollbox.offsetWidth; + var scrollboxscrollw = scrollbox.scrollWidth; + + var offsetw = parseInt(vpw * 0.015); + var paddingw = parseInt(vpw * 0.09); + + var minscrollboxw = 250; + + var maxtabw = 0; + var actabw = 0; + for (var i=0; i<alltabs.length; i++) { + if (activeTab == alltabs[i]) { + actabw = document.getElementById(alltabs[i]).offsetWidth; + if (actabw > maxtabw) { + maxtabw = actabw; + } + } else { + if (document.getElementById(alltabs[i]) != null) { + var thistab = document.getElementById(alltabs[i]); + thistab.style.visibility = 'hidden'; + thistab.style.display = 'block'; + var tabw = document.getElementById(alltabs[i]).offsetWidth; + thistab.style.display = 'none'; + thistab.style.visibility = ''; + if (tabw > maxtabw) { + maxtabw = tabw; + } + } + } + } + + if (maxtabw > 0) { + var newscrollboxw; + if (maxtabw+paddingw+scrollboxscrollw<contenteditorw) { + newscrollboxw = contenteditorw-paddingw-maxtabw; + if (newscrollboxw < minscrollboxw) { + newscrollboxw = minscrollboxw; + } + scrollbox.style.width = newscrollboxw+"px"; + if (newscrollboxw != scrollboxw) { + var newcontentlistw = newscrollboxw-offsetw; + contentlistid.style.width = newcontentlistw+"px"; + } + } else { + newscrollboxw = contenteditorw-paddingw-maxtabw; + if (newscrollboxw < minscrollboxw) { + newscrollboxw = minscrollboxw; + } + scrollbox.style.width = newscrollboxw+"px"; + if (newscrollboxw != scrollboxw) { + var newcontentlistw = newscrollboxw-offsetw; + contentlistid.style.width = newcontentlistw+"px"; + } + } + + if (newscrollboxw != scrollboxw) { + var newscrolltablew = newscrollboxw+offsetw; + scrolltable.style.width = newscrolltablew+"px"; + } + } + + if (contentlistid.offsetWidth != contentlistwstart) { + listwchange = 1; + } + + if (activeTab == 'cc1') { + if (document.getElementById('cc_hrule') != null) { + document.getElementById('cc_hrule').style.width=actabw+"px"; + } + } else { + if (activeTab == 'bb1') { + if (document.getElementById('bb_hrule') != null) { + document.getElementById('bb_hrule').style.width=actabw+"px"; + } + } else { + if (activeTab == 'ee2') { + if (document.getElementById('ee_hrule') != null) { + document.getElementById('ee_hrule').style.width=actabw+"px"; + } + } + } + } + } + if ((chkh == 1) || (listwchange)) { + var primaryheight = document.getElementById("LC_nav_bar").offsetHeight; + var secondaryheight = document.getElementById("LC_secondary_menu").offsetHeight; + var crumbsheight = document.getElementById("LC_breadcrumbs").offsetHeight; + var dccidheight = document.getElementById("dccid").offsetHeight; + + var uploadresultheight = 0; + if (document.getElementById("uploadfileresult") != null) { + uploadresultheight = document.getElementById("uploadfileresult").offsetHeight; + } + var tabbedheight = document.getElementById("tabbededitor").offsetHeight; + var contenteditorheight = document.getElementById("contenteditor").offsetHeight; + var scrollboxheight = scrollbox.offsetHeight; + var scrollboxscrollheight = scrollbox.scrollHeight; + var freevspace = vph-(primaryheight+secondaryheight+crumbsheight+dccidheight+uploadresultheight+tabbedheight+contenteditorheight); + + var minvscrollbox = 200; + var offsetv = 20; + var newscrollboxheight; + if (freevspace < 0) { + newscrollboxheight = scrollboxheight+freevspace-offsetv; + if (newscrollboxheight < minvscrollbox) { + newscrollboxheight = minvscrollbox; + } + scrollbox.style.height = newscrollboxheight + "px"; + } else { + if (scrollboxscrollheight > scrollboxheight) { + if (freevspace > offsetv) { + newscrollboxheight = scrollboxheight+freevspace-offsetv; + if (newscrollboxheight < minvscrollbox) { + newscrollboxheight = minvscrollbox; + } + scrollbox.style.height = newscrollboxheight+"px"; + } + } + } + scrollboxheight = scrollbox.offsetHeight; + var contentlistheight = document.getElementById("contentlist").offsetHeight; + + if (scrollboxscrollheight <= scrollboxheight) { + if ((contentlistheight+offsetv)<scrollboxheight) { + newscrollheight = contentlistheight+offsetv; + scrollbox.style.height = newscrollheight+"px"; + } + } + } + return; +} + +function resizeContentEditor() { + var timer; + clearTimeout(timer) + timer=setTimeout('resize_contentdiv("contentscroll","1","1")',500); +} + +ENDRESIZESCRIPT + return; +} + 1; __END__ @@ -4034,22 +3818,6 @@ Generate "dump" button Generate "export" button -=item exportcourse() - -=item create_ims_store() - -=item build_package() - -=item get_dependencies() - -=item process_content() - -=item replicate_content() - -=item extract_media() - -=item store_template() - =item group_import() Imports the given (name, url) resources into the course