Annotation of loncom/interface/londocs.pm, revision 1.584

1.329     droeschl    1: # The LearningOnline Network
                      2: # Documents
                      3: #
1.584   ! raeburn     4: # $Id: londocs.pm,v 1.583 2014/08/25 00:55:27 raeburn Exp $
1.329     droeschl    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
                     28: 
                     29: package Apache::londocs;
                     30: 
                     31: use strict;
                     32: use Apache::Constants qw(:common :http);
                     33: use Apache::imsexport;
                     34: use Apache::lonnet;
                     35: use Apache::loncommon;
1.383     tempelho   36: use Apache::lonhtmlcommon;
1.329     droeschl   37: use LONCAPA::map();
                     38: use Apache::lonratedt();
                     39: use Apache::lonxml;
                     40: use Apache::lonclonecourse;
                     41: use Apache::lonnavmaps;
1.472     raeburn    42: use Apache::lonnavdisplay();
1.510     raeburn    43: use Apache::lonextresedit();
1.567     raeburn    44: use Apache::lontemplate();
                     45: use Apache::lonsimplepage();
1.329     droeschl   46: use HTML::Entities;
1.488     raeburn    47: use HTML::TokeParser;
1.329     droeschl   48: use GDBM_File;
1.578     raeburn    49: use File::MMagic;
1.329     droeschl   50: use Apache::lonlocal;
                     51: use Cwd;
                     52: use LONCAPA qw(:DEFAULT :match);
                     53: 
                     54: my $iconpath;
                     55: 
                     56: my %hash;
                     57: 
                     58: my $hashtied;
                     59: my %alreadyseen=();
                     60: 
                     61: my $hadchanges;
1.557     raeburn    62: my $suppchanges;
1.329     droeschl   63: 
                     64: 
                     65: my %help=();
                     66: 
                     67: 
                     68: sub mapread {
                     69:     my ($coursenum,$coursedom,$map)=@_;
                     70:     return
                     71:       &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
                     72: 			     $map);
                     73: }
                     74: 
                     75: sub storemap {
1.492     raeburn    76:     my ($coursenum,$coursedom,$map,$contentchg)=@_;
                     77:     my $report;
                     78:     if (($contentchg) && ($map =~ /^default/)) {
                     79:        $report = 1;
                     80:     }
1.329     droeschl   81:     my ($outtext,$errtext)=
                     82:       &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
1.492     raeburn    83: 			      $map,1,$report);
1.329     droeschl   84:     if ($errtext) { return ($errtext,2); }
1.364     bisitz     85: 
1.557     raeburn    86:     if ($map =~ /^default/) {
                     87:         $hadchanges=1;
                     88:     } else {
                     89:         $suppchanges=1;
                     90:     }
1.329     droeschl   91:     return ($errtext,0);
                     92: }
                     93: 
                     94: 
                     95: 
                     96: sub authorhosts {
                     97:     my %outhash=();
                     98:     my $home=0;
                     99:     my $other=0;
                    100:     foreach my $key (keys(%env)) {
                    101: 	if ($key=~/^user\.role\.(au|ca)\.(.+)$/) {
                    102: 	    my $role=$1;
                    103: 	    my $realm=$2;
                    104: 	    my ($start,$end)=split(/\./,$env{$key});
                    105: 	    if (($start) && ($start>time)) { next; }
                    106: 	    if (($end) && (time>$end)) { next; }
                    107: 	    my ($ca,$cd);
                    108: 	    if ($1 eq 'au') {
                    109: 		$ca=$env{'user.name'};
                    110: 		$cd=$env{'user.domain'};
                    111: 	    } else {
                    112: 		($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
                    113: 	    }
                    114: 	    my $allowed=0;
                    115: 	    my $myhome=&Apache::lonnet::homeserver($ca,$cd);
                    116: 	    my @ids=&Apache::lonnet::current_machine_ids();
1.484     raeburn   117: 	    foreach my $id (@ids) {
                    118:                 if ($id eq $myhome) {
                    119:                     $allowed=1;
                    120:                     last;
                    121:                 }
                    122:             }
1.329     droeschl  123: 	    if ($allowed) {
                    124: 		$home++;
1.484     raeburn   125: 		$outhash{'home_'.$ca.':'.$cd}=1;
1.329     droeschl  126: 	    } else {
1.484     raeburn   127: 		$outhash{'otherhome_'.$ca.':'.$cd}=$myhome;
1.329     droeschl  128: 		$other++;
                    129: 	    }
                    130: 	}
                    131:     }
                    132:     return ($home,$other,%outhash);
                    133: }
                    134: 
                    135: 
                    136: sub clean {
                    137:     my ($title)=@_;
                    138:     $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
1.344     bisitz    139:     return $title;
1.329     droeschl  140: }
                    141: 
                    142: 
                    143: 
                    144: sub dumpcourse {
                    145:     my ($r) = @_;
1.408     raeburn   146:     my $crstype = &Apache::loncommon::course_type();
1.567     raeburn   147:     my ($starthash,$js);
                    148:     unless (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
                    149:         $js = <<"ENDJS";
                    150: <script type="text/javascript">
                    151: // <![CDATA[
                    152: 
                    153: function hide_searching() {
                    154:     if (document.getElementById('searching')) {
                    155:         document.getElementById('searching').style.display = 'none';
                    156:     }
                    157:     return;
                    158: }
                    159: 
                    160: // ]]>
                    161: </script>
                    162: ENDJS
                    163:         $starthash = {
                    164:                          add_entries => {'onload' => "hide_searching();"},
                    165:                      };
                    166:     }
1.568     raeburn   167:     $r->print(&Apache::loncommon::start_page('Copy '.$crstype.' Content to Authoring Space',$js,$starthash)."\n".
                    168:               &Apache::lonhtmlcommon::breadcrumbs('Copy '.$crstype.' Content to Authoring Space')."\n");
1.484     raeburn   169:     $r->print(&startContentScreen('tools'));
1.329     droeschl  170:     my ($home,$other,%outhash)=&authorhosts();
1.484     raeburn   171:     unless ($home) {
                    172:         $r->print(&endContentScreen());
                    173:         return '';
                    174:     }
1.329     droeschl  175:     my $origcrsid=$env{'request.course.id'};
                    176:     my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
                    177:     if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
                    178: # Do the dumping
1.484     raeburn   179: 	unless ($outhash{'home_'.$env{'form.authorspace'}}) {
                    180:             $r->print(&endContentScreen());
                    181:             return '';
                    182:         }
1.531     raeburn   183: 	my ($ca,$cd)=split(/\:/,$env{'form.authorspace'});
1.329     droeschl  184: 	$r->print('<h3>'.&mt('Copying Files').'</h3>');
                    185: 	my $title=$env{'form.authorfolder'};
                    186: 	$title=&clean($title);
1.567     raeburn   187:         my ($navmap,$errormsg) =
                    188:             &Apache::loncourserespicker::get_navmap_object($crstype,'dumpdocs');
                    189:         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    190:         my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    191:         my (%maps,%resources,%titles);
                    192:         if (!ref($navmap)) {
                    193:             $r->print($errormsg.
                    194:                       &endContentScreen());
                    195:             return '';
                    196:         } else {
                    197:             &Apache::loncourserespicker::enumerate_course_contents($navmap,\%maps,\%resources,\%titles,
                    198:                                                                    'dumpdocs',$cdom,$cnum);
1.329     droeschl  199: 	}
1.567     raeburn   200:         my @todump = &Apache::loncommon::get_env_multiple('form.archive');
                    201:         my (%tocopy,%replacehash,%lookup,%deps,%display,%result,%depresult,%simpleproblems,%simplepages,
                    202:             %newcontent,%has_simpleprobs);
                    203:         foreach my $item (sort {$a <=> $b} (@todump)) {
                    204:             my $name = $env{'form.namefor_'.$item};
                    205:             if ($resources{$item}) {
                    206:                 my ($map,$id,$res) = &Apache::lonnet::decode_symb($resources{$item});
                    207:                 if ($res =~ m{^uploaded/$cdom/$cnum/\E((?:docs|supplemental)/.+)$}) {
                    208:                     $tocopy{$1} = $name;
                    209:                     $display{$item} = $1;
                    210:                     $lookup{$1} = $item; 
                    211:                 } elsif ($res eq 'lib/templates/simpleproblem.problem') {
                    212:                     $simpleproblems{$item} = {
                    213:                                                 symb => $resources{$item},
                    214:                                                 name => $name,
                    215:                                              };
                    216:                     $display{$item} = 'simpleproblem_'.$name;
                    217:                     if ($map =~ m{^\Quploaded/$cdom/$cnum/\E(.+)$}) {
                    218:                         $has_simpleprobs{$1}{$id} = $item;
                    219:                     }
                    220:                 } elsif ($res =~ m{^adm/$match_domain/$match_username/(\d+)/smppg}) {
                    221:                     my $marker = $1;
                    222:                     my $db_name = &Apache::lonsimplepage::get_db_name($res,$marker,$cdom,$cnum);
                    223:                     $simplepages{$item} = {
                    224:                                             res    => $res,
                    225:                                             title  => $titles{$item},
                    226:                                             db     => $db_name,
                    227:                                             marker => $marker,
                    228:                                             symb   => $resources{$item},
                    229:                                             name   => $name,
                    230:                                           };
                    231:                     $display{$item} = '/'.$res;
                    232:                 }
                    233:             } elsif ($maps{$item}) {
                    234:                 if ($maps{$item} =~ m{^\Quploaded/$cdom/$cnum/\E((?:default|supplemental)_\d+\.(?:sequence|page))$}) {
                    235:                     $tocopy{$1} = $name;
                    236:                     $display{$item} = $1;
                    237:                     $lookup{$1} = $item;
                    238:                 }
                    239:             } else {
                    240:                 next;
                    241:             }
                    242:         }
1.329     droeschl  243: 	my $crs='/uploaded/'.$env{'request.course.id'}.'/';
                    244: 	$crs=~s/\_/\//g;
1.567     raeburn   245:         my $mm = new File::MMagic;
                    246:         my $prefix = "/uploaded/$cdom/$cnum/";
                    247:         %replacehash = %tocopy;
                    248:         foreach my $item (sort(keys(%simpleproblems))) {
                    249:             my $content = &Apache::imsexport::simpleproblem($simpleproblems{$item}{'symb'});
                    250:             $newcontent{$display{$item}} = $content;
                    251:         }
                    252:         my $gateway = Apache::lonhtmlgateway->new('web');
                    253:         foreach my $item (sort(keys(%simplepages))) {
                    254:             if (ref($simplepages{$item}) eq 'HASH') {
                    255:                 my $pagetitle = $simplepages{$item}{'title'};
                    256:                 my %fields = &Apache::lonnet::dump($simplepages{$item}{'db'},$cdom,$cnum);
                    257:                 my %contents;
                    258:                 foreach my $field (keys(%fields)) {
                    259:                     if ($field =~ /^(?:aaa|bbb|ccc)_(\w+)$/) {
                    260:                         my $name = $1;
                    261:                         my $msg = $fields{$field};
                    262:                         if ($name eq 'webreferences') {
                    263:                             if ($msg =~ m{^https?://}) {
                    264:                                 $contents{$name} = '<a href="'.$msg.'"><tt>'.$msg.'</tt></a>';
                    265:                             }
                    266:                         } else {
                    267:                             $msg = &Encode::decode('utf8',$msg);
                    268:                             $msg = $gateway->process_outgoing_html($msg,1);
                    269:                             $contents{$name} = $msg;
                    270:                         }
                    271:                     } elsif ($field eq 'uploaded.photourl') {
                    272:                         my $marker = $simplepages{$item}{marker};
                    273:                         if ($fields{$field} =~ m{^\Q$prefix\E(simplepage/$marker/.+)$}) {
                    274:                             my $filepath = $1;
                    275:                             my ($relpath,$fname) = ($filepath =~ m{^(.+/)([^/]+)$});
                    276:                             if ($fname ne '') {
                    277:                                 $fname=~s/\.(\w+)$//;
                    278:                                 my $ext=$1;
                    279:                                 $fname = &clean($fname);
                    280:                                 $fname.='.'.$ext;
                    281:                                 $contents{image} = '<img src="'.$relpath.$fname.'" alt="Image" />';
                    282:                                 $replacehash{$filepath} = $relpath.$fname;
                    283:                                 $deps{$item}{$filepath} = 1;
                    284:                             }
                    285:                         }
                    286:                     }
                    287:                 }
                    288:                 $replacehash{'/'.$simplepages{$item}{'res'}} = $simplepages{$item}{'name'};
                    289:                 $lookup{'/'.$simplepages{$item}{'res'}} = $item;
                    290:                 my $content = '
                    291: <html>
                    292: <head>
                    293: <title>'.$pagetitle.'</title>
                    294: </head>
                    295: <body bgcolor="#ffffff">';
                    296:                 if ($contents{title}) {
                    297:                     $content .= "\n".'<h2>'.$contents{title}.'</h2>';
                    298:                 }
                    299:                 if ($contents{image}) {
                    300:                     $content .= "\n".$contents{image};
                    301:                 }
                    302:                 if ($contents{content}) {
                    303:                     $content .= '
                    304: <div class="LC_Box">
1.577     bisitz    305: <h4 class="LC_hcell">'.&mt('Content').'</h4>'.
1.567     raeburn   306: $contents{content}.'
                    307: </div>';
                    308:                 }
                    309:                 if ($contents{webreferences}) {
                    310:                     $content .= ' 
                    311: <div class="LC_Box">
1.577     bisitz    312: <h4 class="LC_hcell">'.&mt('Web References').'</h4>'.
1.567     raeburn   313: $contents{webreferences}.'
                    314: </div>';
                    315:                 }
                    316:                 $content .= '
                    317: </body>
                    318: </html>
                    319: ';
                    320:                 $newcontent{'/'.$simplepages{$item}{res}} = $content; 
                    321:             }
                    322:         }
                    323: 	foreach my $item (keys(%tocopy)) {
                    324:             unless ($item=~/\.(sequence|page)$/) {
                    325:                 my $currurlpath = $prefix.$item;
                    326:                 my $currdirpath = &Apache::lonnet::filelocation('',$currurlpath);
                    327:                 &recurse_html($mm,$prefix,$currdirpath,$currurlpath,$item,$lookup{$item},\%replacehash,\%deps);
                    328:             }
                    329:         }
                    330:         foreach my $num (sort {$a <=> $b} (@todump)) {
                    331:             my $src = $display{$num};
                    332:             next if ($src eq '');
                    333:             my @needcopy = ();
                    334:             if ($replacehash{$src}) {
                    335:                 push(@needcopy,$src);
                    336:                 if (ref($deps{$num}) eq 'HASH') {
                    337:                     foreach my $dep (sort(keys(%{$deps{$num}}))) {
                    338:                         if ($replacehash{$dep}) {
                    339:                             push(@needcopy,$dep);
                    340:                         }
                    341:                     }
                    342:                 }
                    343:             } elsif ($src =~ /^simpleproblem_/) {
                    344:                 push(@needcopy,$src);
                    345:             }
                    346:             next if (@needcopy == 0);
                    347:             my ($result,$depresult);
                    348:             for (my $i=0; $i<@needcopy; $i++) {
                    349:                 my $item = $needcopy[$i];
                    350:                 my $newfilename;
                    351:                 if ($simpleproblems{$num}) {
                    352:                     $newfilename=$title.'/'.$simpleproblems{$num}{'name'};
                    353:                 } else {
                    354: 	            $newfilename=$title.'/'.$replacehash{$item};
                    355:                 }
                    356: 	        $newfilename=~s/\.(\w+)$//;
                    357: 	        my $ext=$1;
                    358: 	        $newfilename=&clean($newfilename);
                    359: 	        $newfilename.='.'.$ext;
                    360:                 my ($newrelpath) = ($newfilename =~ m{^\Q$title/\E(.+)$}); 
                    361:                 if ($newrelpath ne $replacehash{$item}) {
                    362:                     $replacehash{$item} = $newrelpath;
                    363:                 }
                    364: 	        my @dirs=split(/\//,$newfilename);
                    365: 	        my $path=$r->dir_config('lonDocRoot')."/priv/$cd/$ca";
                    366: 	        my $makepath=$path;
                    367: 	        my $fail;
                    368:                 my $origin;
                    369: 	        for (my $i=0;$i<$#dirs;$i++) {
                    370: 		    $makepath.='/'.$dirs[$i];
                    371: 		    unless (-e $makepath) {
                    372: 		        unless(mkdir($makepath,0755)) { 
                    373:                             $fail = &mt('Directory creation failed.');
                    374:                         }
                    375: 		    }
                    376: 	        }
                    377:                 if ($i == 0) {
                    378: 	            $result = '<br /><tt>'.$item.'</tt> => <tt>'.$newfilename.'</tt>: ';
                    379:                 } else {
                    380:                     $depresult .= '<li><tt>'.$item.'</tt> => <tt>'.$newfilename.'</tt> '.
                    381:                                   '<span class="LC_fontsize_small" style="font-weight: bold;">'.
                    382:                                   &mt('(dependency)').'</span>: ';
                    383:                 }
                    384:                 if (-e $path.'/'.$newfilename) {
                    385:                     $fail = &mt('Destination already exists -- not overwriting.'); 
                    386: 	        } else {
                    387:                     if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
                    388:                         if (($item =~ m{^/adm/$match_domain/$match_username/\d+/smppg}) ||
                    389:                             ($item =~ /^simpleproblem_/)) {
                    390:                             print $fh $newcontent{$item};
                    391:                         } else {
                    392:                             my $fileloc = &Apache::lonnet::filelocation('',$prefix.$item);
                    393:                             if (-e $fileloc) {
                    394:                                 if ($item=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
                    395:                                     if ((($1 eq 'sequence') || ($1 eq 'page')) &&
                    396:                                         (ref($has_simpleprobs{$item}) eq 'HASH')) {
                    397:                                         my %changes = %{$has_simpleprobs{$item}};
                    398:                                         my $content = &Apache::lonclonecourse::rewritefile(
                    399:                      &Apache::lonclonecourse::readfile($env{'request.course.id'},$item),
                    400:                                                       (%replacehash,$crs => '')
                    401:                                                                                           );
                    402:                                         my $updatedcontent = '';
                    403:                                         my $parser = HTML::TokeParser->new(\$content);
                    404:                                         $parser->attr_encoded(1);
                    405:                                         while (my $token = $parser->get_token) {
                    406:                                             if ($token->[0] eq 'S') {
                    407:                                                 if (($token->[1] eq 'resource') &&
                    408:                                                     ($token->[2]->{'src'} eq '/res/lib/templates/simpleproblem.problem') && 
                    409:                                                     ($changes{$token->[2]->{'id'}})) {
                    410:                                                     my $id = $token->[2]->{'id'};
                    411:                                                     $updatedcontent .= '<'.$token->[1];
                    412:                                                     foreach my $attrib (@{$token->[3]}) {
                    413:                                                         next unless ($attrib =~ /^(src|type|title|id)$/);
                    414:                                                         if ($attrib eq 'src') {
                    415:                                                             my ($file) = ($display{$changes{$id}} =~ /^\Qsimpleproblem_\E(.+)$/); 
                    416:                                                             if ($file) {
                    417:                                                                 $updatedcontent .= ' '.$attrib.'="'.$file.'"';
                    418:                                                             } else {
                    419:                                                                 $updatedcontent .= ' '.$attrib.'="'.$token->[2]->{$attrib}.'"'; 
                    420:                                                             }
                    421:                                                         } else {
                    422:                                                             $updatedcontent .= ' '.$attrib.'="'.$token->[2]->{$attrib}.'"';
                    423:                                                         }
                    424:                                                     }
                    425:                                                     $updatedcontent .= ' />'."\n";
                    426:                                                 } else {
                    427:                                                     $updatedcontent .= $token->[4]."\n";
                    428:                                                 }
                    429:                                              } else {
                    430:                                                  $updatedcontent .= $token->[2];
                    431:                                              }
                    432:                                          }
                    433:                                          print $fh $updatedcontent;
                    434:                                     } else {  
                    435: 		                        print $fh &Apache::lonclonecourse::rewritefile(
                    436:                      &Apache::lonclonecourse::readfile($env{'request.course.id'},$item),
                    437: 		                                      (%replacehash,$crs => '')
                    438: 							                              );
                    439:                                     }
                    440:                                 } else {
                    441: 		                    print $fh
                    442:                                         &Apache::lonclonecourse::readfile($env{'request.course.id'},$item);
                    443: 		                }
                    444:                             } else {
                    445:                                 $fail = &mt('Source does not exist.');  
                    446:                             }
                    447:                         }
                    448:                         $fh->close();
                    449: 	            } else {
                    450: 		        $fail = &mt('Could not write to destination.');
                    451:                     }
                    452: 	        }
                    453:                 my $text;
                    454: 	        if ($fail) {
                    455:                     $text = '<span class="LC_error">'.&mt('fail').('&nbsp;'x3).$fail.'</span>';
                    456: 	        } else {
                    457:                     $text = '<span class="LC_success">'.&mt('ok').'</span>';
                    458:                 }
                    459:                 if ($i == 0) {
                    460:                     $result .= $text;
                    461:                 } else {
                    462:                     $depresult .= $text.'</li>';
                    463: 	        }
                    464:             }
                    465:             $r->print($result);
                    466:             if ($depresult) {
                    467:                 $r->print('<ul>'.$depresult.'</ul>');
                    468:             }
                    469:         }
                    470:     } else {
                    471:         my ($navmap,$errormsg) =
                    472:             &Apache::loncourserespicker::get_navmap_object($crstype,'dumpdocs');
                    473:         if (!ref($navmap)) {
                    474:             $r->print($errormsg);
                    475:         } else {
                    476:             $r->print('<div id="searching">'.&mt('Searching ...').'</div>');
                    477:             $r->rflush();
                    478:             my ($preamble,$formname);
                    479:             $formname = 'dumpdoc';
                    480: 	    unless ($home==1) {
                    481: 	        $preamble = '<div class="LC_left_float">'.
                    482: 		            '<fieldset><legend>'.
                    483:                             &mt('Select the Authoring Space').
                    484:                             '</legend><select name="authorspace">';
1.329     droeschl  485: 	    }
1.567     raeburn   486:             my @orderspaces = ();
                    487: 	    foreach my $key (sort(keys(%outhash))) {
                    488:                 if ($key=~/^home_(.+)$/) {
                    489:                     if ($1 eq $env{'user.name'}.':'.$env{'user.domain'}) {
                    490:                         unshift(@orderspaces,$1);
                    491:                     } else {
                    492:                         push(@orderspaces,$1);
                    493:                     }
                    494:                 } 
                    495:             }
1.569     raeburn   496:             if ($home>1) {
                    497:                 $preamble .= '<option value="" selected="selected">'.&mt('Select').'</option>';
                    498:             }
1.567     raeburn   499:             foreach my $user (@orderspaces) {
1.329     droeschl  500: 		if ($home==1) {
1.567     raeburn   501: 		    $preamble .= '<input type="hidden" name="authorspace" value="'.$user.'" />';
1.329     droeschl  502: 		} else {
1.567     raeburn   503: 		    $preamble .= '<option value="'.$user.'">'.$user.' - '.
                    504: 			         &Apache::loncommon::plainname(split(/\:/,$user)).'</option>';
                    505: 	        }
1.329     droeschl  506: 	    }
1.567     raeburn   507: 	    unless ($home==1) {
                    508: 	        $preamble .= '</select></fieldset></div>'."\n";
1.329     droeschl  509: 	    }
1.567     raeburn   510: 	    my $title=$origcrsdata{'description'};
                    511: 	    $title=~s/[\/\s]+/\_/gs;
1.329     droeschl  512: 	    $title=&clean($title);
1.567     raeburn   513: 	    $preamble .= '<div class="LC_left_float">'.
                    514:                          '<fieldset><legend>'.&mt('Folder in Authoring Space').'</legend>'.
                    515:                          '<input type="text" size="50" name="authorfolder" value="'.
                    516:                          $title.'" />'.
                    517:                          '</fieldset></div><div style="padding:0;clear:both;margin:0;border:0"></div>'."\n";
                    518:             my %uploadedfiles;
                    519: 	    &tiehash();
                    520: 	    foreach my $file (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
                    521: 	        my ($ext)=($file=~/\.(\w+)$/);
                    522: # FIXME Check supplemental here
                    523: 	        my $title=$hash{'title_'.$hash{
                    524: 		                'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$file}};
                    525: 	        if (!$title) {
                    526: 		    $title=$file;
                    527: 	        } else {
                    528: 		    $title=~s|/|_|g;
                    529: 	        }
                    530: 	        $title=~s/\.(\w+)$//;
                    531: 	        $title=&clean($title);
                    532: 	        $title.='.'.$ext;
                    533: #	    $r->print("\n<td><input type='text' size='60' name='namefor_".$file."' value='".$title."' /></td>"
                    534:                 $uploadedfiles{$file} = $title;
                    535: 	    }
                    536: 	    &untiehash();
                    537:             $r->print(&Apache::loncourserespicker::create_picker($navmap,'dumpdocs',$formname,$crstype,undef,
                    538:                                                                  undef,undef,$preamble,$home,\%uploadedfiles));
                    539:         }
1.329     droeschl  540:     }
1.484     raeburn   541:     $r->print(&endContentScreen());
1.329     droeschl  542: }
                    543: 
1.567     raeburn   544: sub recurse_html {
                    545:     my ($mm,$prefix,$currdirpath,$currurlpath,$container,$item,$replacehash,$deps) = @_;
                    546:     return unless ((ref($replacehash) eq 'HASH') && (ref($deps) eq 'HASH'));
                    547:     my (%allfiles,%codebase);
                    548:     if (&Apache::lonnet::extract_embedded_items($currdirpath,\%allfiles,\%codebase) eq 'ok') {
                    549:         if (keys(%allfiles)) {
                    550:             foreach my $dependency (keys(%allfiles)) {
                    551:                 next if (($dependency =~ m{^/(res|adm)/}) || ($dependency =~ m{^https?://}));
                    552:                 my ($depurl,$relfile,$newcontainer);
                    553:                 if ($dependency =~ m{^/}) {
                    554:                     if ($dependency =~ m{^\Q$currurlpath/\E(.+)$}) {
                    555:                         $relfile = $1;
                    556:                         if ($dependency =~ m{^\Q$prefix\E(.+)$}) {
                    557:                             $newcontainer = $1;
                    558:                             next if ($replacehash->{$newcontainer});
                    559:                         }
                    560:                         $depurl = $dependency;
                    561:                     } else {
                    562:                         next;
                    563:                     }
                    564:                 } else {
                    565:                     $relfile = $dependency;
                    566:                     $depurl = $currurlpath;
                    567:                     $depurl =~ s{[^/]+$}{};  
                    568:                     $depurl .= $dependency;
                    569:                     ($newcontainer) = ($depurl =~ m{^\Q$prefix\E(.+)$}); 
                    570:                 }
                    571:                 next if ($relfile eq '');
                    572:                 my $newname = $replacehash->{$container};
                    573:                 $newname =~ s{[^/]+$}{};
                    574:                 $replacehash->{$newcontainer} = $newname.$relfile;
                    575:                 $deps->{$item}{$newcontainer} = 1;
                    576:                 my ($newurlpath) = ($depurl =~ m{^(.*)/[^/]+$});  
                    577:                 my $depfile = &Apache::lonnet::filelocation('',$depurl);
                    578:                 my $type = $mm->checktype_filename($depfile);
                    579:                 if ($type eq 'text/html') {
                    580:                     &recurse_html($mm,$prefix,$depfile,$newurlpath,$newcontainer,$item,$replacehash,$deps);
                    581:                 }
                    582:             }
                    583:         }
                    584:     }
                    585:     return;
                    586: }
                    587: 
1.329     droeschl  588: sub group_import {
                    589:     my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
1.529     raeburn   590:     my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,
                    591:         %removeparam,$importuploaded,$fixuperrors);
                    592:     $allmaps = {};
1.329     droeschl  593:     while (@files) {
                    594: 	my ($name, $url, $residx) = @{ shift(@files) };
1.344     bisitz    595:         if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$})
1.329     droeschl  596: 	     && ($caller eq 'londocs')
                    597: 	     && (!&Apache::lonnet::stat_file($url))) {
1.364     bisitz    598: 
1.329     droeschl  599:             my $errtext = '';
                    600:             my $fatal = 0;
                    601:             my $newmapstr = '<map>'."\n".
                    602:                             '<resource id="1" src="" type="start"></resource>'."\n".
                    603:                             '<link from="1" to="2" index="1"></link>'."\n".
                    604:                             '<resource id="2" src="" type="finish"></resource>'."\n".
                    605:                             '</map>';
                    606:             $env{'form.output'}=$newmapstr;
                    607:             my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
                    608:                                                 'output',$1.$2);
1.534     raeburn   609:             if ($result !~ m{^/uploaded/}) {
1.329     droeschl  610:                 $errtext.='Map not saved: A network error occurred when trying to save the new map. ';
                    611:                 $fatal = 2;
                    612:             }
                    613:             if ($fatal) {
                    614:                 return ($errtext,$fatal);
                    615:             }
                    616:         }
                    617: 	if ($url) {
1.529     raeburn   618:             if (($caller eq 'londocs') &&
                    619:                 ($folder =~ /^default/)) {
1.534     raeburn   620:                 if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {
1.529     raeburn   621:                     my $chome = &Apache::lonnet::homeserver($coursenum,$coursedom);
                    622:                     my $cid = $coursedom.'_'.$coursenum;
                    623:                     $allmaps =
                    624:                         &Apache::loncommon::allmaps_incourse($coursedom,$coursenum,
                    625:                                                              $chome,$cid);
                    626:                     $donechk = 1;
                    627:                 }
                    628:                 if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) {
                    629:                     &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
                    630:                                          \%addedmaps,\%hierarchy,\%titles,$allmaps);
                    631:                     $importuploaded = 1;
                    632:                 } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) {
                    633:                     next if ($allmaps->{$url});
                    634:                 }
                    635:             }
1.344     bisitz    636: 	    if (!$residx
1.329     droeschl  637: 		|| defined($LONCAPA::map::zombies[$residx])) {
                    638: 		$residx = &LONCAPA::map::getresidx($url,$residx);
                    639: 		push(@LONCAPA::map::order, $residx);
                    640: 	    }
                    641: 	    my $ext = 'false';
                    642: 	    if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
                    643: 	    $name = &LONCAPA::map::qtunescape($name);
1.534     raeburn   644:             if ($name eq '') {
1.538     raeburn   645:                 $name = &LONCAPA::map::qtunescape(&mt('Web Page'));
1.534     raeburn   646:             }
                    647:             if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) {
                    648:                 my $filepath = $1;
                    649:                 my $fname = $name;
                    650:                 if ($fname =~ /^\W+$/) {
                    651:                     $fname = 'web';
                    652:                 } else {
                    653:                     $fname =~ s/\W/_/g;
                    654:                 }
                    655:                 if (length($fname > 15)) {
                    656:                     $fname = substr($fname,0,14);
                    657:                 }
                    658:                 my $initialtext = &mt('Replace with your own content.');
                    659:                 my $newhtml = <<END;
1.545     raeburn   660: <html>
1.534     raeburn   661: <head>
                    662: <title>$name</title>
                    663: </head>
                    664: <body bgcolor="#ffffff">
                    665: $initialtext
                    666: </body>
                    667: </html>
                    668: END
                    669:                 $env{'form.output'}=$newhtml;
                    670:                 my $result = 
                    671:                     &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
                    672:                                                           'output',
                    673:                                                           "$filepath/$residx/$fname.html");
                    674:                 if ($result =~ m{^/uploaded/}) {
                    675:                     $url = $result;
                    676:                     if ($filepath =~ /^supplemental/) {
                    677:                         $name = time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                    678:                                 $env{'user.domain'}.'___&&&___'.$name;
                    679:                     }
                    680:                 } else {
                    681:                     return (&mt('Failed to save new web page.'),1);
                    682:                 }
                    683:             }
1.538     raeburn   684:             $url  = &LONCAPA::map::qtunescape($url);
1.344     bisitz    685: 	    $LONCAPA::map::resources[$residx] =
1.329     droeschl  686: 		join(':', ($name, $url, $ext, 'normal', 'res'));
                    687: 	}
                    688:     }
1.529     raeburn   689:     if ($importuploaded) {
                    690:         my %import_errors;
                    691:         my %updated = (
                    692:                           removefrommap => \%removefrommap,
                    693:                           removeparam   => \%removeparam,
                    694:                       );
1.533     raeburn   695:         my ($result,$msgsarray,$lockerror) = 
                    696:             &apply_fixups($folder,1,$coursedom,$coursenum,\%import_errors,\%updated);
1.529     raeburn   697:         if (keys(%import_errors) > 0) {
1.530     raeburn   698:             $fixuperrors =
1.529     raeburn   699:                 '<p span class="LC_warning">'."\n".
                    700:                 &mt('The following files are either dependencies of a web page or references within a folder and/or composite page for which errors occurred during import:')."\n".
                    701:                 '<ul>'."\n";
                    702:             foreach my $key (sort(keys(%import_errors))) {
                    703:                 $fixuperrors .= '<li>'.$key.'</li>'."\n";
                    704:             }
                    705:             $fixuperrors .= '</ul></p>'."\n";
                    706:         }
1.533     raeburn   707:         if (ref($msgsarray) eq 'ARRAY') {
                    708:             if (@{$msgsarray} > 0) {
                    709:                 $fixuperrors .= '<p class="LC_info">'.
                    710:                                 join('<br />',@{$msgsarray}).
                    711:                                 '</p>';
                    712:             }
                    713:         }
                    714:         if ($lockerror) {
                    715:             $fixuperrors .= '<p class="LC_error">'.
                    716:                             $lockerror.
                    717:                             '</p>';
                    718:         }
1.529     raeburn   719:     }
                    720:     my ($errtext,$fatal) =
                    721:         &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
1.557     raeburn   722:     unless ($fatal) {
                    723:         if ($folder =~ /^supplemental/) {
                    724:             &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
1.561     raeburn   725:             my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                    726:                                             $folder.'.'.$container);
1.557     raeburn   727:         }
                    728:     }
1.529     raeburn   729:     return ($errtext,$fatal,$fixuperrors);
1.329     droeschl  730: }
                    731: 
                    732: sub log_docs {
1.494     raeburn   733:     return &Apache::lonnet::write_log('course','docslog',@_);
1.329     droeschl  734: }
                    735: 
                    736: {
                    737:     my @oldresources=();
                    738:     my @oldorder=();
                    739:     my $parmidx;
                    740:     my %parmaction=();
                    741:     my %parmvalue=();
                    742:     my $changedflag;
                    743: 
                    744:     sub snapshotbefore {
                    745:         @oldresources=@LONCAPA::map::resources;
                    746:         @oldorder=@LONCAPA::map::order;
                    747:         $parmidx=undef;
                    748:         %parmaction=();
                    749:         %parmvalue=();
                    750:         $changedflag=0;
                    751:     }
                    752: 
                    753:     sub remember_parms {
                    754:         my ($idx,$parameter,$action,$value)=@_;
                    755:         $parmidx=$idx;
                    756:         $parmaction{$parameter}=$action;
                    757:         $parmvalue{$parameter}=$value;
                    758:         $changedflag=1;
                    759:     }
                    760: 
                    761:     sub log_differences {
                    762:         my ($plain)=@_;
                    763:         my %storehash=('folder' => $plain,
                    764:                        'currentfolder' => $env{'form.folder'});
                    765:         if ($parmidx) {
                    766:            $storehash{'parameter_res'}=$oldresources[$parmidx];
                    767:            foreach my $parm (keys(%parmaction)) {
                    768:               $storehash{'parameter_action_'.$parm}=$parmaction{$parm};
                    769:               $storehash{'parameter_value_'.$parm}=$parmvalue{$parm};
                    770:            }
                    771:         }
                    772:         my $maxidx=$#oldresources;
                    773:         if ($#LONCAPA::map::resources>$#oldresources) {
                    774:            $maxidx=$#LONCAPA::map::resources;
                    775:         }
                    776:         for (my $idx=0; $idx<=$maxidx; $idx++) {
                    777:            if ($LONCAPA::map::resources[$idx] ne $oldresources[$idx]) {
                    778:               $storehash{'before_resources_'.$idx}=$oldresources[$idx];
                    779:               $storehash{'after_resources_'.$idx}=$LONCAPA::map::resources[$idx];
                    780:               $changedflag=1;
                    781:            }
                    782:            if ($LONCAPA::map::order[$idx] ne $oldorder[$idx]) {
                    783:               $storehash{'before_order_res_'.$idx}=$oldresources[$oldorder[$idx]];
                    784:               $storehash{'after_order_res_'.$idx}=$LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
                    785:               $changedflag=1;
                    786:            }
                    787:         }
                    788: 	$storehash{'maxidx'}=$maxidx;
                    789:         if ($changedflag) { &log_docs(\%storehash); }
                    790:     }
                    791: }
                    792: 
                    793: sub docs_change_log {
1.484     raeburn   794:     my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_;
1.486     raeburn   795:     my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/);
1.483     raeburn   796:     my $js = '<script type="text/javascript">'."\n".
                    797:              '// <![CDATA['."\n".
                    798:              &Apache::loncommon::display_filter_js('docslog')."\n".
1.486     raeburn   799:              &editing_js($env{'user.domain'},$env{'user.name'},$supplementalflag)."\n".
1.483     raeburn   800:              &history_tab_js()."\n".
1.484     raeburn   801:              &Apache::lonratedt::editscript('simple')."\n".
1.483     raeburn   802:              '// ]]>'."\n".
                    803:              '</script>'."\n";
1.484     raeburn   804:     $r->print(&Apache::loncommon::start_page('Content Change Log',$js));
                    805:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Change Log'));
1.489     raeburn   806:     $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs')));
1.484     raeburn   807:     my %orderhash;
                    808:     my $container='sequence';
                    809:     my $pathitem;
1.519     raeburn   810:     if ($env{'form.folderpath'} =~ /\:1$/) {
1.484     raeburn   811:         $container='page';
                    812:     }
1.519     raeburn   813:     my $folderpath=$env{'form.folderpath'};
                    814:     if ($folderpath eq '') {
1.548     raeburn   815:         $folderpath = 'default&'.&escape(&mt('Main Content').':::::');
1.519     raeburn   816:     }
                    817:     $pathitem = '<input type="hidden" name="folderpath" value="'.
                    818:                 &HTML::Entities::encode($folderpath,'<>&"').'" />';
1.484     raeburn   819:     my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
                    820:     my $jumpto = $readfile;
                    821:     $jumpto =~ s{^/}{};
                    822:     my $tid = 1;
1.489     raeburn   823:     if ($supplementalflag) {
                    824:         $tid = 2;
                    825:     }
1.509     raeburn   826:     my ($breadcrumbtrail) = 
                    827:         &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1);
1.484     raeburn   828:     $r->print($breadcrumbtrail.
                    829:               &generate_edit_table($tid,\%orderhash,undef,$iconpath,$jumpto,
                    830:               $readfile));
1.329     droeschl  831:     my %docslog=&Apache::lonnet::dump('nohist_docslog',
                    832:                                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                    833:                                       $env{'course.'.$env{'request.course.id'}.'.num'});
                    834: 
                    835:     if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); }
                    836: 
                    837:     my %saveable_parameters = ('show' => 'scalar',);
                    838:     &Apache::loncommon::store_course_settings('docs_log',
                    839:                                               \%saveable_parameters);
                    840:     &Apache::loncommon::restore_course_settings('docs_log',
                    841:                                                 \%saveable_parameters);
                    842:     if (!$env{'form.show'}) { $env{'form.show'}=10; }
1.452     www       843: # FIXME: internationalization seems wrong here
1.329     droeschl  844:     my %lt=('hiddenresource' => 'Resources hidden',
                    845: 	    'encrypturl'     => 'URL hidden',
                    846: 	    'randompick'     => 'Randomly pick',
                    847: 	    'randomorder'    => 'Randomly ordered',
                    848: 	    'set'            => 'set to',
                    849: 	    'del'            => 'deleted');
1.484     raeburn   850:     my $filter = &Apache::loncommon::display_filter('docslog')."\n".
                    851:                  $pathitem."\n".
                    852:                  '<input type="hidden" name="folder" value="'.$env{'form.folder'}.'" />'.
                    853:                  ('&nbsp;'x2).'<input type="submit" value="'.&mt('Display').'" />';
                    854:     $r->print('<div class="LC_left_float">'.
                    855:               '<fieldset><legend>'.&mt('Display of Content Changes').'</legend>'."\n".
                    856:               &makedocslogform($filter,1).
                    857:               '</fieldset></div><br clear="all" />');
1.329     droeschl  858:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
                    859:               '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Folder').'</th><th>'.&mt('Before').'</th><th>'.
                    860:               &mt('After').'</th>'.
                    861:               &Apache::loncommon::end_data_table_header_row());
                    862:     my $shown=0;
                    863:     foreach my $id (sort { $docslog{$b}{'exe_time'}<=>$docslog{$a}{'exe_time'} } (keys(%docslog))) {
                    864: 	if ($env{'form.displayfilter'} eq 'currentfolder') {
                    865: 	    if ($docslog{$id}{'logentry'}{'currentfolder'} ne $folder) { next; }
                    866: 	}
                    867:         my @changes=keys(%{$docslog{$id}{'logentry'}});
                    868:         if ($env{'form.displayfilter'} eq 'containing') {
                    869: 	    my $wholeentry=$docslog{$id}{'exe_uname'}.':'.$docslog{$id}{'exe_udom'}.':'.
                    870: 		&Apache::loncommon::plainname($docslog{$id}{'exe_uname'},$docslog{$id}{'exe_udom'});
                    871: 	    foreach my $key (@changes) {
                    872: 		$wholeentry.=':'.$docslog{$id}{'logentry'}{$key};
                    873: 	    }
1.344     bisitz    874: 	    if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }
1.329     droeschl  875: 	}
                    876:         my $count = 0;
                    877:         my $time =
                    878:             &Apache::lonlocal::locallocaltime($docslog{$id}{'exe_time'});
                    879:         my $plainname =
                    880:             &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},
                    881:                                           $docslog{$id}{'exe_udom'});
                    882:         my $about_me_link =
                    883:             &Apache::loncommon::aboutmewrapper($plainname,
                    884:                                                $docslog{$id}{'exe_uname'},
                    885:                                                $docslog{$id}{'exe_udom'});
                    886:         my $send_msg_link='';
                    887:         if ((($docslog{$id}{'exe_uname'} ne $env{'user.name'})
                    888:              || ($docslog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
                    889:             $send_msg_link ='<br />'.
                    890:                 &Apache::loncommon::messagewrapper(&mt('Send message'),
                    891:                                                    $docslog{$id}{'exe_uname'},
                    892:                                                    $docslog{$id}{'exe_udom'});
                    893:         }
                    894:         $r->print(&Apache::loncommon::start_data_table_row());
                    895:         $r->print('<td>'.$time.'</td>
                    896:                        <td>'.$about_me_link.
                    897:                   '<br /><tt>'.$docslog{$id}{'exe_uname'}.
                    898:                                   ':'.$docslog{$id}{'exe_udom'}.'</tt>'.
                    899:                   $send_msg_link.'</td><td>'.
                    900:                   $docslog{$id}{'logentry'}{'folder'}.'</td><td>');
1.488     raeburn   901:         my $is_supp = 0; 
                    902:         if ($docslog{$id}{'logentry'}{'currentfolder'} =~ /^supplemental/) {
                    903:             $is_supp = 1;
                    904:         }
1.329     droeschl  905: # Before
                    906: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                    907: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                    908: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
                    909: 	    if ($oldname ne $newname) {
1.488     raeburn   910:                 my $shown = &LONCAPA::map::qtescape($oldname);
                    911:                 if ($is_supp) {
                    912:                     $shown = &Apache::loncommon::parse_supplemental_title($shown);
                    913:                 }
                    914:                 $r->print($shown);
1.329     droeschl  915: 	    }
                    916: 	}
                    917: 	$r->print('<ul>');
                    918: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                    919:             if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) {
1.488     raeburn   920:                 my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]);
                    921:                 if ($is_supp) {
                    922:                     $shown = &Apache::loncommon::parse_supplemental_title($shown);
                    923:                 }
                    924: 		$r->print('<li>'.$shown.'</li>');
1.329     droeschl  925: 	    }
                    926: 	}
                    927: 	$r->print('</ul>');
                    928: # After
                    929:         $r->print('</td><td>');
                    930: 
                    931: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                    932: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                    933: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
                    934: 	    if ($oldname ne '' && $oldname ne $newname) {
1.488     raeburn   935:                 my $shown = &LONCAPA::map::qtescape($newname);
                    936:                 if ($is_supp) {
                    937:                     $shown = &Apache::loncommon::parse_supplemental_title(&LONCAPA::map::qtescape($newname));
                    938:                 }
                    939:                 $r->print($shown);
1.329     droeschl  940: 	    }
1.364     bisitz    941: 	}
1.329     droeschl  942: 	$r->print('<ul>');
                    943: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                    944:             if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) {
1.488     raeburn   945:                 my $shown = &LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]);
                    946:                 if ($is_supp) {
                    947:                     $shown = &Apache::loncommon::parse_supplemental_title($shown);
                    948:                 }
                    949:                 $r->print('<li>'.$shown.'</li>');
1.329     droeschl  950: 	    }
                    951: 	}
                    952: 	$r->print('</ul>');
                    953: 	if ($docslog{$id}{'logentry'}{'parameter_res'}) {
                    954: 	    $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':<ul>');
                    955: 	    foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder') {
                    956: 		if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
1.452     www       957: # FIXME: internationalization seems wrong here
1.329     droeschl  958: 		    $r->print('<li>'.
                    959: 			      &mt($lt{$parameter}.' '.$lt{$docslog{$id}{'logentry'}{'parameter_action_'.$parameter}}.' [_1]',
                    960: 				  $docslog{$id}{'logentry'}{'parameter_value_'.$parameter})
                    961: 			      .'</li>');
                    962: 		}
                    963: 	    }
                    964: 	    $r->print('</ul>');
                    965: 	}
                    966: # End
                    967:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
                    968:         $shown++;
                    969:         if (!($env{'form.show'} eq &mt('all')
                    970:               || $shown<=$env{'form.show'})) { last; }
                    971:     }
1.484     raeburn   972:     $r->print(&Apache::loncommon::end_data_table()."\n".
                    973:               &makesimpleeditform($pathitem)."\n".
                    974:               '</div></div>');
                    975:     $r->print(&endContentScreen());
1.329     droeschl  976: }
                    977: 
                    978: sub update_paste_buffer {
1.492     raeburn   979:     my ($coursenum,$coursedom,$folder) = @_;
1.538     raeburn   980:     my (@possibles,%removals,%cuts);
                    981:     if ($env{'form.multiremove'}) {
                    982:         $env{'form.multiremove'} =~ s/,$//;
                    983:         map { $removals{$_} = 1; } split(/,/,$env{'form.multiremove'});
                    984:     }
                    985:     if (($env{'form.multicopy'}) || ($env{'form.multicut'})) {
                    986:         if ($env{'form.multicut'}) {
                    987:             $env{'form.multicut'} =~ s/,$//;
                    988:             foreach my $item (split(/,/,$env{'form.multicut'})) {
                    989:                 unless ($removals{$item}) {
                    990:                     $cuts{$item} = 1;
                    991:                     push(@possibles,$item.':cut');
                    992:                 }
                    993:             }
                    994:         }
                    995:         if ($env{'form.multicopy'}) {
                    996:             $env{'form.multicopy'} =~ s/,$//;
                    997:             foreach my $item (split(/,/,$env{'form.multicopy'})) {
                    998:                 unless ($removals{$item} || $cuts{$item}) {
                    999:                     push(@possibles,$item.':copy'); 
                   1000:                 }
                   1001:             }
                   1002:         }
                   1003:     } elsif ($env{'form.markcopy'}) {
                   1004:         @possibles = split(/,/,$env{'form.markcopy'});
                   1005:     }
1.329     droeschl 1006: 
1.538     raeburn  1007:     return if (@possibles == 0);
1.329     droeschl 1008:     return if (!defined($env{'form.copyfolder'}));
                   1009: 
                   1010:     my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                   1011: 				    $env{'form.copyfolder'});
1.538     raeburn  1012:     return if ($fatal);
                   1013: 
                   1014:     my %curr_groups = &Apache::longroup::coursegroups();
1.364     bisitz   1015: 
1.538     raeburn  1016: # Retrieve current paste buffer suffixes.
                   1017:     my @currpaste = split(/,/,$env{'docs.markedcopies'});
                   1018:     my (%pasteurls,@newpaste);
                   1019: 
                   1020: # Construct identifiers for current contents of user's paste buffer
                   1021:     if (@currpaste) {
                   1022:         foreach my $suffix (@currpaste) {
                   1023:              my $cid = $env{'docs.markedcopy_crs_'.$suffix};
                   1024:              my $url = $env{'docs.markedcopy_url_'.$suffix};
                   1025:              if (($cid =~ /^$match_domain(?:_)$match_courseid$/) &&
                   1026:                  ($url ne '')) {
1.564     raeburn  1027:                  $pasteurls{$cid.'_'.$url} = 1;
1.538     raeburn  1028:              }
                   1029:         }
                   1030:     }
                   1031: 
                   1032: # Mark items for copying (skip any items already in user's paste buffer)
                   1033:     my %addtoenv;
                   1034:                   
                   1035:     foreach my $item (@possibles) {
                   1036:         my ($orderidx,$cmd) = split(/:/,$item);
                   1037:         next if ($orderidx =~ /\D/);
                   1038:         next unless (($cmd eq 'cut') || ($cmd eq 'copy') || ($cmd eq 'remove'));
                   1039:         my ($title,$url)=split(':',$LONCAPA::map::resources[$orderidx]);
                   1040:         my %denied = &action_restrictions($coursenum,$coursedom,
                   1041:                                           &LONCAPA::map::qtescape($url),
                   1042:                                           $env{'form.folderpath'},\%curr_groups);
                   1043:         next if ($denied{'copy'});
                   1044:         $url=~s{http(&colon;|:)//https(&colon;|:)//}{https$2//};
                   1045:         next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url}));
                   1046:         my ($suffix,$errortxt,$locknotfreed) =
                   1047:             &new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste');
                   1048:         push(@newpaste,$suffix);
                   1049:         if ($locknotfreed) {
                   1050:             return $locknotfreed;
                   1051:             last;
                   1052:         }
                   1053:         if (&is_supplemental_title($title)) {
                   1054:             &Apache::lonnet::appenv({'docs.markedcopy_supplemental_'.$suffix => $title});
                   1055: 	    ($title) = &Apache::loncommon::parse_supplemental_title($title);
                   1056:         }
1.329     droeschl 1057: 
1.538     raeburn  1058:         $addtoenv{'docs.markedcopy_title_'.$suffix} = $title,
                   1059:         $addtoenv{'docs.markedcopy_url_'.$suffix}   = $url,
                   1060:         $addtoenv{'docs.markedcopy_cmd_'.$suffix}   = $cmd,
                   1061:         $addtoenv{'docs.markedcopy_crs_'.$suffix}   = $env{'request.course.id'};
                   1062:  
                   1063:         if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) {
                   1064:             my $prefix = $1;
                   1065:             my $subdir =$2;
                   1066:             if ($subdir eq '') {
                   1067:                 $subdir = $prefix;
1.492     raeburn  1068:             }
1.538     raeburn  1069:             my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
                   1070:             &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
                   1071:                                  \%hierarchy,\%titles,\%allmaps);
                   1072:             if (ref($hierarchy{$url}) eq 'HASH') {
                   1073:                 my ($nested,$nestednames);
                   1074:                 &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
                   1075:                 $nested =~ s/\&$//;
                   1076:                 $nestednames =~ s/\Q___&&&___\E$//;
                   1077:                 if ($nested ne '') {
                   1078:                     $addtoenv{'docs.markedcopy_nested_'.$suffix} = $nested;
                   1079:                 }
                   1080:                 if ($nestednames ne '') {
                   1081:                     $addtoenv{'docs.markedcopy_nestednames_'.$suffix} = $nestednames;
                   1082:                 }
1.492     raeburn  1083:             }
                   1084:         }
                   1085:     }
1.538     raeburn  1086:     if (@newpaste) {
                   1087:         $addtoenv{'docs.markedcopies'} = join(',',(@currpaste,@newpaste));
                   1088:     }
1.492     raeburn  1089:     &Apache::lonnet::appenv(\%addtoenv);
1.329     droeschl 1090:     delete($env{'form.markcopy'});
1.576     raeburn  1091:     return;
1.329     droeschl 1092: }
                   1093: 
1.492     raeburn  1094: sub recurse_uploaded_maps {
                   1095:     my ($url,$dir,$hierarchy,$titlesref,$nestref,$namesref) = @_;
                   1096:     if (ref($hierarchy->{$url}) eq 'HASH') {
                   1097:         my @maps = map { $hierarchy->{$url}{$_}; } sort { $a <=> $b } (keys(%{$hierarchy->{$url}}));
                   1098:         my @titles = map { $titlesref->{$url}{$_}; } sort { $a <=> $b } (keys(%{$titlesref->{$url}}));
                   1099:         my (@uploaded,@names,%shorter);
                   1100:         for (my $i=0; $i<@maps; $i++) {
                   1101:             my ($inner) = ($maps[$i] =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_(\d+)\.(?:page|sequence)$});
                   1102:             if ($inner ne '') {
                   1103:                 push(@uploaded,$inner);
                   1104:                 push(@names,&escape($titles[$i]));
                   1105:                 $shorter{$maps[$i]} = $inner;
                   1106:             }
                   1107:         }
                   1108:         $$nestref .= "$dir:".join(',',@uploaded).'&';
                   1109:         $$namesref .= "$dir:".(join(',',@names)).'___&&&___';
                   1110:         foreach my $map (@maps) {
                   1111:             if ($shorter{$map} ne '') {
                   1112:                 &recurse_uploaded_maps($map,$shorter{$map},$hierarchy,$titlesref,$nestref,$namesref);
                   1113:             }
                   1114:         }
                   1115:     }
                   1116:     return;
                   1117: }
                   1118: 
1.329     droeschl 1119: sub print_paste_buffer {
1.492     raeburn  1120:     my ($r,$container,$folder,$coursedom,$coursenum) = @_;
1.538     raeburn  1121:     return if (!defined($env{'docs.markedcopies'}));
1.329     droeschl 1122: 
1.538     raeburn  1123:     unless (($env{'form.pastemarked'}) || ($env{'form.clearmarked'})) {
                   1124:         return if ($env{'docs.markedcopies'} eq '');
1.488     raeburn  1125:     }
                   1126: 
1.538     raeburn  1127:     my @currpaste = split(/,/,$env{'docs.markedcopies'});
                   1128:     my ($pasteitems,@pasteable);
1.575     raeburn  1129:     my $clipboardcount = 0;
1.488     raeburn  1130: 
1.538     raeburn  1131: # Construct identifiers for current contents of user's paste buffer
                   1132:     foreach my $suffix (@currpaste) {
                   1133:         next if ($suffix =~ /\D/);
                   1134:         my $cid = $env{'docs.markedcopy_crs_'.$suffix};
                   1135:         my $url = $env{'docs.markedcopy_url_'.$suffix};
                   1136:         if (($cid =~ /^$match_domain\_$match_courseid$/) &&
                   1137:             ($url ne '')) {
1.575     raeburn  1138:             $clipboardcount ++;
1.538     raeburn  1139:             my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
                   1140:                 $canpaste,$nopaste,$othercrs,$areachange);
                   1141:             my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
                   1142:             if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//} ) {
                   1143:                 $is_external = 1;
                   1144:             }
                   1145:             if ($folder =~ /^supplemental/) {
                   1146:                 $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
                   1147:                 unless ($canpaste) {
                   1148:                     $nopaste = &mt('Paste into Supplemental Content unavailable.');
                   1149:                 }
                   1150:             } else {
                   1151:                 $canpaste = 1;
                   1152:             }
                   1153:             if ($canpaste) {
                   1154:                 if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
                   1155:                     my $srcdom = $1;
                   1156:                     my $srcnum = $2;
                   1157:                     my $rem = $3;
                   1158:                     if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) {
                   1159:                         $othercourse = 1;
                   1160:                         if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
                   1161:                             if ($canpaste) {
1.539     raeburn  1162:                                 $othercrs = '<br />'.&mt('(from another course)');
1.538     raeburn  1163:                             }
                   1164:                         } else {
                   1165:                             $canpaste = 0;
                   1166:                             $nopaste = &mt('Paste from another course unavailable.'); 
                   1167:                         }
                   1168:                     }
                   1169:                     if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) {
                   1170:                         my $prefix = $1;
                   1171:                         $parent = $2;
                   1172:                         if ($folder !~ /^\Q$prefix\E/) {
                   1173:                             $areachange = 1;
                   1174:                         }
                   1175:                         $is_uploaded_map = 1;
1.492     raeburn  1176:                     }
                   1177:                 }
                   1178:             }
1.538     raeburn  1179:             if ($canpaste) {
                   1180:                push(@pasteable,$suffix);
                   1181:             }
                   1182:             my $buffer;
                   1183:             if ($is_external) {
                   1184:                 $buffer = &mt('External Resource').': '.
                   1185:                     &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.
                   1186:                     &LONCAPA::map::qtescape($url).')';
                   1187:             } else {
                   1188:                 my $icon = &Apache::loncommon::icon($extension);
                   1189:                 if ($extension eq 'sequence' &&
                   1190:                     $url =~ m{/default_\d+\.sequence$}x) {
                   1191:                     $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
                   1192:                     $icon .= '/navmap.folder.closed.gif';
                   1193:                 }
                   1194:                 $buffer = '<img src="'.$icon.'" alt="" class="LC_icon" />'.
                   1195:                           ': '.
                   1196:                           &Apache::loncommon::parse_supplemental_title(
                   1197:                              &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}));
                   1198:             }
                   1199:             $pasteitems .= '<div class="LC_left_float">';
                   1200:             my ($options,$onclick);
                   1201:             if (($canpaste) && (!$areachange) && (!$othercourse) &&
                   1202:                 ($env{'docs.markedcopy_cmd_'.$suffix} eq 'cut')) {
                   1203:                 if (($is_uploaded_map) ||
                   1204:                     ($url =~ /(bulletinboard|smppg)$/) ||
                   1205:                     ($url =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) {
                   1206:                     $options = &paste_options($suffix,$is_uploaded_map,$parent);
                   1207:                     $onclick= 'onclick="showOptions(this,'."'$suffix'".');" ';
                   1208:                 }
                   1209:             }
                   1210:             $pasteitems .= '<label><input type="checkbox" name="pasting" id="pasting_'.$suffix.'" value="'.$suffix.'" '.$onclick.'/>'.$buffer.'</label>';
                   1211:             if ($nopaste) {
                   1212:                  $pasteitems .= $nopaste;   
                   1213:             } else {
                   1214:                 if ($othercrs) {
                   1215:                     $pasteitems .= $othercrs;
                   1216:                 }
                   1217:                 if ($options) {
                   1218:                     $pasteitems .= $options;
1.492     raeburn  1219:                 }
                   1220:             }
1.538     raeburn  1221:             $pasteitems .= '</div>';
                   1222:         }
                   1223:     }
                   1224:     if ($pasteitems eq '') {
                   1225:         &Apache::lonnet::delenv('docs.markedcopies');
                   1226:     }
                   1227:     my ($pasteform,$form_start,$buttons,$form_end);
                   1228:     if ($pasteitems) {
                   1229:         $pasteitems .= '<div style="padding:0;clear:both;margin:0;border:0"></div>';
1.541     raeburn  1230:         $form_start = '<form name="pasteform" action="/adm/coursedocs" method="post" onsubmit="return validateClipboard();">';
1.538     raeburn  1231:         if (@pasteable) {
1.575     raeburn  1232:             my $value = &mt('Paste to current folder');
                   1233:             if ($container eq 'page') {
                   1234:                 $value = &mt('Paste to current page');
                   1235:             } 
                   1236:             $buttons = '<input type="submit" name="pastemarked" value="'.$value.'" />'.('&nbsp;'x2);
                   1237:         }
                   1238:         $buttons .= '<input type="submit" name="clearmarked" value="'.&mt('Remove from clipboard').'" />'.('&nbsp;'x2);
                   1239:         if ($clipboardcount > 1) {
                   1240:             $buttons .=
                   1241:                 '<span style="text-decoration:line-through">'.('&nbsp;'x20).'</span>'.('&nbsp;'x2).
                   1242:                 '<input type="button" name="checkallclip" value="'.&mt('Check all').'" style="height:20px;" onclick="checkClipboard();" />'.
                   1243:                 ('&nbsp;'x2).
                   1244:                 '<input type="button" name="uncheckallclip" value="'.&mt('Uncheck all').'" style="height:20px;" onclick="uncheckClipboard();" />'.
                   1245:                 ('&nbsp;'x2);
1.492     raeburn  1246:         }
1.575     raeburn  1247:         $form_end = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />'.
                   1248:                     '</form>';
1.538     raeburn  1249:     } else {
                   1250:         $pasteitems = &mt('Clipboard is empty');
1.488     raeburn  1251:     }
1.538     raeburn  1252:     $r->print($form_start
                   1253:              .'<fieldset>'
                   1254:              .'<legend>'.&mt('Clipboard').('&nbsp;' x2).$buttons.'</legend>'
                   1255:              .$pasteitems
                   1256:              .'</fieldset>'
                   1257:              .$form_end);
                   1258: }
                   1259: 
                   1260: sub paste_options {
                   1261:     my ($suffix,$is_uploaded_map,$parent) = @_;
                   1262:     my ($copytext,$movetext);
                   1263:     if ($is_uploaded_map) {
                   1264:         $copytext = &mt('Copy to new folder');
                   1265:         $movetext = &mt('Move old');
                   1266:     } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /bulletinboard$/) {
                   1267:         $copytext = &mt('Copy to new board');
                   1268:         $movetext = &mt('Move (not posts)');
                   1269:     } elsif ($env{'docs.markedcopy_url_'.$suffix} =~ /smppg$/) {
                   1270:         $copytext = &mt('Copy to new page');
                   1271:         $movetext = &mt('Move');
1.533     raeburn  1272:     } else {
1.538     raeburn  1273:         $copytext = &mt('Copy to new file');
                   1274:         $movetext = &mt('Move');
                   1275:     }
                   1276:     my $output = '<br />'.
                   1277:                  '<span id="pasteoptionstext_'.$suffix.'" class="LC_fontsize_small LC_nobreak"></span>'.
                   1278:                  '<div id="pasteoptions_'.$suffix.'" class="LC_dccid" style="display:none;"><span class="LC_nobreak">'.('&nbsp;'x 4).
                   1279:                  '<label>'.
                   1280:                  '<input type="radio" name="docs.markedcopy_options_'.$suffix.'" value="new" checked="checked" />'.
                   1281:                  $copytext.'</label></span>'.('&nbsp;'x2).' '.
                   1282:                  '<span class="LC_nobreak"><label>'.
                   1283:                  '<input type="radio" name="docs.markedcopy_options_'.$suffix.'" value="move" />'.
                   1284:                  $movetext.'</label></span>';
                   1285:     if (($is_uploaded_map) && ($env{'docs.markedcopy_nested_'.$suffix})) {
                   1286:         $output .= '<br /><fieldset><legend>'.&mt('Folder to paste contains sub-folders').
                   1287:                    '</legend><table border="0">';
                   1288:         my @pastemaps = split(/\&/,$env{'docs.markedcopy_nested_'.$suffix});
                   1289:         my @titles = split(/\Q___&&&___\E/,$env{'docs.markedcopy_nestednames_'.$suffix});
                   1290:         my $lastdir = $parent;
                   1291:         my %depths = (
                   1292:                        $lastdir => 0,
                   1293:                      );
                   1294:         my (%display,%deps);
                   1295:         for (my $i=0; $i<@pastemaps; $i++) {
                   1296:             ($lastdir,my $subfolderstr) = split(/\:/,$pastemaps[$i]);
                   1297:             my ($namedir,$esctitlestr) = split(/\:/,$titles[$i]);
                   1298:             my @subfolders = split(/,/,$subfolderstr);
                   1299:             $deps{$lastdir} = \@subfolders;
                   1300:             my @subfoldertitles = map { &unescape($_); } split(/,/,$esctitlestr);
                   1301:             my $depth = $depths{$lastdir} + 1;
                   1302:             my $offset = int($depth * 4);
                   1303:             my $indent = ('&nbsp;' x $offset);
                   1304:             for (my $j=0; $j<@subfolders; $j++) {
                   1305:                 $depths{$subfolders[$j]} = $depth;
                   1306:                 $display{$subfolders[$j]} =
                   1307:                     '<tr><td>'.$indent.$subfoldertitles[$j].'&nbsp;</td>'.
                   1308:                     '<td><label>'.
                   1309:                     '<input type="radio" name="docs.markedcopy_'.$suffix.'_'.$subfolders[$j].'" value="new" checked="checked" />'.&mt('Copy to new').'</label>'.('&nbsp;' x2).
                   1310:                     '<label>'.
                   1311:                     '<input type="radio" name="docs.markedcopy_'.$suffix.'_'.$subfolders[$j].'" value="move" />'.
                   1312:                     &mt('Move old').'</label>'.
                   1313:                     '</td></tr>';
                   1314:              }
1.492     raeburn  1315:         }
1.538     raeburn  1316:         &recurse_print(\$output,$parent,\%deps,\%display);
                   1317:         $output .= '</table></fieldset>';
1.329     droeschl 1318:     }
1.538     raeburn  1319:     $output .= '</div>';
                   1320:     return $output;
1.488     raeburn  1321: }
                   1322: 
1.492     raeburn  1323: sub recurse_print {
1.538     raeburn  1324:     my ($outputref,$dir,$deps,$display) = @_;
                   1325:     $$outputref .= $display->{$dir}."\n";
1.492     raeburn  1326:     if (ref($deps->{$dir}) eq 'ARRAY') {
                   1327:         foreach my $subdir (@{$deps->{$dir}}) {
1.538     raeburn  1328:             &recurse_print($outputref,$subdir,$deps,$display);
1.492     raeburn  1329:         }
                   1330:     }
                   1331: }
                   1332: 
1.488     raeburn  1333: sub supp_pasteable {
                   1334:     my ($url) = @_;
                   1335:     if (($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//}) ||
                   1336:         (($url =~ /\.sequence$/) && ($url =~ m{^/uploaded/})) ||
                   1337:         ($url =~ m{^/uploaded/$match_domain/$match_courseid/(docs|supplemental)/(default|\d+)/\d+/}) ||
                   1338:         ($url =~ m{^/adm/$match_domain/$match_username/aboutme}) ||
                   1339:         ($url =~ m{^/public/$match_domain/$match_courseid/syllabus})) {
                   1340:         return 1;
                   1341:     }
                   1342:     return;
1.329     droeschl 1343: }
                   1344: 
1.492     raeburn  1345: sub paste_popup_js {
                   1346:     my %lt = &Apache::lonlocal::texthash(
1.538     raeburn  1347:                                           show => 'Show Options',
                   1348:                                           hide => 'Hide Options',
1.541     raeburn  1349:                                           none => 'No items selected from clipboard.',
1.492     raeburn  1350:                                         );
                   1351:     return <<"END";
                   1352: 
1.538     raeburn  1353: function showPasteOptions(suffix) {
                   1354:     document.getElementById('pasteoptions_'+suffix).style.display='block';
                   1355:     document.getElementById('pasteoptionstext_'+suffix).innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:hidePasteOptions(\\''+suffix+'\\');" class="LC_menubuttons_link">$lt{'hide'}</a>';
1.492     raeburn  1356:     return;
                   1357: }
                   1358: 
1.538     raeburn  1359: function hidePasteOptions(suffix) {
                   1360:     document.getElementById('pasteoptions_'+suffix).style.display='none';
                   1361:     document.getElementById('pasteoptionstext_'+suffix).innerHTML ='&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:showPasteOptions(\\''+suffix+'\\')" class="LC_menubuttons_link">$lt{'show'}</a>';
                   1362:     return;
                   1363: }
                   1364: 
                   1365: function showOptions(caller,suffix) {
                   1366:     if (document.getElementById('pasteoptionstext_'+suffix)) {
                   1367:         if (caller.checked) {
                   1368:             document.getElementById('pasteoptionstext_'+suffix).innerHTML ='&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:showPasteOptions(\\''+suffix+'\\')" class="LC_menubuttons_link">$lt{'show'}</a>';
                   1369:         } else {
                   1370:             document.getElementById('pasteoptionstext_'+suffix).innerHTML ='';
                   1371:         }
                   1372:         if (document.getElementById('pasteoptions_'+suffix)) {
                   1373:             document.getElementById('pasteoptions_'+suffix).style.display='none';
                   1374:         }
                   1375:     }
1.492     raeburn  1376:     return;
                   1377: }
                   1378: 
1.541     raeburn  1379: function validateClipboard() {
                   1380:     var numchk = 0;
                   1381:     if (document.pasteform.pasting.length > 1) {
                   1382:         for (var i=0; i<document.pasteform.pasting.length; i++) {
                   1383:             if (document.pasteform.pasting[i].checked) {
                   1384:                 numchk ++;
                   1385:             }
                   1386:         }
                   1387:     } else {
                   1388:         if (document.pasteform.pasting.type == 'checkbox') {
                   1389:             if (document.pasteform.pasting.checked) {
                   1390:                 numchk ++; 
                   1391:             } 
                   1392:         }
                   1393:     }
                   1394:     if (numchk > 0) { 
                   1395:         return true;
                   1396:     } else {
                   1397:         alert("$lt{'none'}");
                   1398:         return false;
                   1399:     }
                   1400: }
                   1401: 
1.575     raeburn  1402: function checkClipboard() {
                   1403:     if (document.pasteform.pasting.length > 1) {
                   1404:         for (var i=0; i<document.pasteform.pasting.length; i++) {
                   1405:             document.pasteform.pasting[i].checked = true;
                   1406:         } 
                   1407:     }
                   1408:     return;
                   1409: }
                   1410: 
                   1411: function uncheckClipboard() {
                   1412:     if (document.pasteform.pasting.length >1) {
                   1413:         for (var i=0; i<document.pasteform.pasting.length; i++) {
                   1414:             document.pasteform.pasting[i].checked = false;
                   1415:         }
                   1416:     }
                   1417:     return;
                   1418: }
                   1419: 
1.492     raeburn  1420: END
                   1421: 
                   1422: }
                   1423: 
1.329     droeschl 1424: sub do_paste_from_buffer {
1.492     raeburn  1425:     my ($coursenum,$coursedom,$folder,$container,$errors) = @_;
1.329     droeschl 1426: 
1.538     raeburn  1427: # Array of items in paste buffer
                   1428:     my (@currpaste,%pastebuffer,%allerrors);
                   1429:     @currpaste = split(/,/,$env{'docs.markedcopies'});
                   1430: 
1.492     raeburn  1431: # Early out if paste buffer is empty
1.538     raeburn  1432:     if (@currpaste == 0) {
1.492     raeburn  1433:         return ();
1.538     raeburn  1434:     } 
                   1435:     map { $pastebuffer{$_} = 1; } @currpaste;
                   1436: 
                   1437: # Array of items selected items to paste
                   1438:     my @reqpaste = &Apache::loncommon::get_env_multiple('form.pasting');
                   1439: 
                   1440: # Early out if nothing selected to paste
                   1441:     if (@reqpaste == 0) {
                   1442:         return();
                   1443:     }
                   1444:     my @topaste;
                   1445:     foreach my $suffix (@reqpaste) {
                   1446:         next if ($suffix =~ /\D/);
                   1447:         next unless (exists($pastebuffer{$suffix}));
                   1448:         push(@topaste,$suffix);
                   1449:     }
                   1450: 
                   1451: # Early out if nothing available to paste
                   1452:     if (@topaste == 0) {
                   1453:         return();
1.329     droeschl 1454:     }
                   1455: 
1.538     raeburn  1456:     my (%msgs,%before,%after,@dopaste,%is_map,%notinsupp,%notincrs,%duplicate,
1.564     raeburn  1457:         %prefixchg,%srcdom,%srcnum,%marktomove,$save_err,$lockerrors,$allresult);
1.538     raeburn  1458: 
                   1459:     foreach my $suffix (@topaste) {
                   1460:         my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
1.492     raeburn  1461: # Supplemental content may only include certain types of content
                   1462: # Early out if pasted content is not supported in Supplemental area
1.538     raeburn  1463:         if ($folder =~ /^supplemental/) {
                   1464:             unless (&supp_pasteable($url)) {
                   1465:                 $notinsupp{$suffix} = 1;
                   1466:                 next;
                   1467:             }
1.492     raeburn  1468:         }
1.538     raeburn  1469:         if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/}) {
                   1470:             my $srcd = $1;
                   1471:             my $srcn = $2;
1.492     raeburn  1472: # When paste buffer was populated using an active role in a different course
1.538     raeburn  1473: # check for mdc privilege in the course from which the resource was pasted
                   1474:             if (($srcd ne $coursedom) || ($srcn ne $coursenum)) {
                   1475:                 unless ($env{"user.priv.cm./$srcd/$srcn"} =~ /\Q:mdc&F\E/) {
                   1476:                     $notincrs{$suffix} = 1;
                   1477:                     next;
                   1478:                 }
1.491     raeburn  1479:             }
1.538     raeburn  1480:             $srcdom{$suffix} = $srcd;
                   1481:             $srcnum{$suffix} = $srcn;
1.491     raeburn  1482:         }
1.538     raeburn  1483: 
                   1484:         push(@dopaste,$suffix);
                   1485:         if ($url=~/\.(page|sequence)$/) {
                   1486:             $is_map{$suffix} = 1; 
                   1487:         }
                   1488: 
                   1489:         if ($url =~ m{^/uploaded/$match_domain/$match_courseid/([^/]+)}) {
                   1490:             my $oldprefix = $1;
1.492     raeburn  1491: # When pasting content from Main Content to Supplemental Content and vice versa 
                   1492: # URLs will contain different paths (which depend on whether pasted item is
                   1493: # a folder/page or a document.   
1.538     raeburn  1494:             if (($folder =~ /^supplemental/) && (($oldprefix =~ /^default/) || ($oldprefix eq 'docs'))) {
                   1495:                 $prefixchg{$suffix} = 'docstosupp';
                   1496:             } elsif (($folder =~ /^default/) && ($oldprefix =~ /^supplemental/)) {
                   1497:                 $prefixchg{$suffix} = 'supptodocs';
                   1498:             }
1.491     raeburn  1499: 
1.492     raeburn  1500: # If pasting an uploaded map, get list of contained uploaded maps.
1.538     raeburn  1501:             if ($env{'docs.markedcopy_nested_'.$suffix}) {
                   1502:                 my @nested;
                   1503:                 my ($type) = ($oldprefix =~ /^(default|supplemental)/);
                   1504:                 my @items = split(/\&/,$env{'docs.markedcopy_nested_'.$suffix});
                   1505:                 my @deps = map { /\d+:([\d,]+$)/ } @items;
                   1506:                 foreach my $dep (@deps) {
                   1507:                     if ($dep =~ /,/) {
                   1508:                         push(@nested,split(/,/,$dep));
                   1509:                     } else {
                   1510:                         push(@nested,$dep);
                   1511:                     }
1.492     raeburn  1512:                 }
1.538     raeburn  1513:                 foreach my $item (@nested) {
                   1514:                     if ($env{'form.docs.markedcopy_'.$suffix.'_'.$item} eq 'move') {
                   1515:                         push(@{$marktomove{$suffix}},$type.'_'.$item);
                   1516:                     }
1.492     raeburn  1517:                 }
                   1518:             }
1.488     raeburn  1519:         }
                   1520:     }
                   1521: 
1.538     raeburn  1522: # Early out if nothing available to paste
                   1523:     if (@dopaste == 0) {
                   1524:         return ();
                   1525:     }
                   1526: 
                   1527: # Populate message hash and hashes used for main content <=> supplemental content
                   1528: # changes    
                   1529: 
                   1530:     %msgs = &Apache::lonlocal::texthash (
                   1531:                 notinsupp => 'Paste failed: content type is not supported within Supplemental Content',
                   1532:                 notincrs  => 'Paste failed: Item is from a different course which you do not have rights to edit.',
                   1533:                 duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
                   1534:             );
                   1535: 
                   1536:     %before = (
                   1537:                  docstosupp => {
                   1538:                                    map => 'default',
                   1539:                                    doc => 'docs',
                   1540:                                },
                   1541:                  supptodocs => {
                   1542:                                    map => 'supplemental',
                   1543:                                    doc => 'supplemental',
                   1544:                                },
                   1545:               );
                   1546: 
                   1547:     %after = (
                   1548:                  docstosupp => {
                   1549:                                    map => 'supplemental',
                   1550:                                    doc => 'supplemental'
                   1551:                                },
                   1552:                  supptodocs => {
                   1553:                                    map => 'default',
                   1554:                                    doc => 'docs',
                   1555:                                },
                   1556:              );
                   1557: 
                   1558: # Retrieve information about all course maps in main content area 
                   1559: 
                   1560:     my $allmaps = {};
                   1561:     if ($folder =~ /^default/) {
                   1562:         $allmaps =
                   1563:             &Apache::loncommon::allmaps_incourse($coursedom,$coursenum,
                   1564:                                                  $env{"course.$env{'request.course.id'}.home"},
                   1565:                                                  $env{'request.course.id'});
                   1566:     }
                   1567: 
                   1568:     my (@toclear,%mapurls,%lockerrs,%msgerrs,%results);
                   1569: 
                   1570: # Loop over the items to paste
                   1571:     foreach my $suffix (@dopaste) {
1.329     droeschl 1572: # Maps need to be copied first
1.538     raeburn  1573:         my (%removefrommap,%removeparam,%addedmaps,%rewrites,%retitles,%copies,
                   1574:             %dbcopies,%zombies,%params,%docmoves,%mapmoves,%mapchanges,%newsubdir,
                   1575:             %newurls,%tomove);
                   1576:         if (ref($marktomove{$suffix}) eq 'ARRAY') {
                   1577:             map { $tomove{$_} = 1; } @{$marktomove{$suffix}};
                   1578:         }
                   1579:         my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
                   1580:         my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix});
                   1581:         my $oldurl = $url;
                   1582:         if ($is_map{$suffix}) {
1.491     raeburn  1583: # If pasting a map, check if map contains other maps
1.538     raeburn  1584:             my (%hierarchy,%titles);
                   1585:             &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
                   1586:                                  \%addedmaps,\%hierarchy,\%titles,$allmaps);
                   1587:             if ($url=~ m{^/uploaded/}) {
                   1588:                 my $newurl;
                   1589:                 unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
                   1590:                     ($newurl,my $error) = 
                   1591:                         &get_newmap_url($url,$folder,$prefixchg{$suffix},$coursedom,
                   1592:                                         $coursenum,$srcdom{$suffix},$srcnum{$suffix},
                   1593:                                         \$title,$allmaps,\%newurls);
                   1594:                     if ($error) {
                   1595:                         $allerrors{$suffix} = $error;
                   1596:                         next;
                   1597:                     }
                   1598:                     if ($newurl ne '') {
                   1599:                         if ($newurl ne $url) {
                   1600:                             if ($newurl =~ /(?:default|supplemental)_(\d+).(?:sequence|page)$/) {
                   1601:                                 $newsubdir{$url} = $1;
                   1602:                             }
                   1603:                             $mapchanges{$url} = 1;
1.492     raeburn  1604:                         }
1.538     raeburn  1605:                     }
                   1606:                 }
                   1607:                 if (($srcdom{$suffix} ne $coursedom) ||
                   1608:                     ($srcnum{$suffix} ne $coursenum) ||
                   1609:                     ($prefixchg{$suffix}) || (($newurl ne '') && ($newurl ne $url))) {
                   1610:                     unless (&url_paste_fixups($url,$folder,$prefixchg{$suffix},
                   1611:                                               $coursedom,$coursenum,$srcdom{$suffix},
                   1612:                                               $srcnum{$suffix},$allmaps,\%rewrites,
                   1613:                                               \%retitles,\%copies,\%dbcopies,
                   1614:                                               \%zombies,\%params,\%mapmoves,
                   1615:                                               \%mapchanges,\%tomove,\%newsubdir,
                   1616:                                               \%newurls)) {
                   1617:                         $mapmoves{$url} = 1;
                   1618:                     }
                   1619:                     $url = $newurl;
                   1620:                 } elsif ($env{'docs.markedcopy_nested_'.$suffix}) {
                   1621:                     &url_paste_fixups($url,$folder,$prefixchg{$suffix},$coursedom,
                   1622:                                       $coursenum,$srcdom{$suffix},$srcnum{$suffix},
                   1623:                                       $allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies,
                   1624:                                       \%zombies,\%params,\%mapmoves,\%mapchanges,
                   1625:                                       \%tomove,\%newsubdir,\%newurls); 
                   1626:                 }
                   1627:             } elsif ($url=~m {^/res/}) {
                   1628: # published map can only exists once, so remove from paste buffer when done
                   1629:                 push(@toclear,$suffix);
                   1630: # if pasting published map (main content area only) check map not already in course
                   1631:                 if ($folder =~ /^default/) {
                   1632:                     if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) {
                   1633:                         $duplicate{$suffix} = 1; 
                   1634:                         next;
1.492     raeburn  1635:                     }
1.491     raeburn  1636:                 }
                   1637:             }
1.538     raeburn  1638:         }
                   1639:         if ($url=~ m{/(bulletinboard|smppg)$}) {
                   1640:             my $prefix = $1;
                   1641:             #need to copy the db contents to a new one, unless this is a move.
                   1642:             my %info = (
                   1643:                          src  => $url,
                   1644:                          cdom => $coursedom,
                   1645:                          cnum => $coursenum,
                   1646:             );
                   1647:             unless ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
                   1648:                 my (%lockerr,$msg); 
                   1649:                 my ($newurl,$result,$errtext) =
                   1650:                     &dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
                   1651:                 if ($result eq 'ok') {
                   1652:                     $url = $newurl;
                   1653:                     $title=&mt('Copy of').' '.$title;
                   1654:                 } else {
                   1655:                     if ($prefix eq 'smppg') {
                   1656:                         $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext;
                   1657:                     } elsif ($prefix eq 'bulletinboard') {
1.565     bisitz   1658:                         $msg = &mt('Paste failed: An error occurred when copying the discussion board.').' '.$errtext;
1.538     raeburn  1659:                     }
                   1660:                     $results{$suffix} = $result;
                   1661:                     $msgerrs{$suffix} = $msg;
                   1662:                     $lockerrs{$suffix} = $lockerr{$prefix}; 
                   1663:                     next;
                   1664: 	        }
                   1665:                 if ($lockerr{$prefix}) {
                   1666:                     $lockerrs{$suffix} = $lockerr{$prefix};  
1.491     raeburn  1667:                 }
1.489     raeburn  1668:             }
                   1669:         }
1.538     raeburn  1670:         $title = &LONCAPA::map::qtunescape($title);
                   1671:         my $ext='false';
                   1672:         if ($url=~m{^http(|s)://}) { $ext='true'; }
                   1673:         if ($env{'docs.markedcopy_supplemental_'.$suffix}) {
                   1674:             if ($folder !~ /^supplemental/) {
                   1675:                 (undef,undef,$title) =
                   1676:                     &Apache::loncommon::parse_supplemental_title($env{'docs.markedcopy_supplemental_'.$suffix});
                   1677:             }
                   1678:         } else {
                   1679:             if ($folder=~/^supplemental/) {
                   1680:                 $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                   1681:                        $env{'user.domain'}.'___&&&___'.$title;
1.491     raeburn  1682:             }
1.533     raeburn  1683:         }
1.491     raeburn  1684: 
                   1685: # For uploaded files (excluding pages/sequences) path in copied file is changed
                   1686: # if paste is from Main to Supplemental (or vice versa), or if pasting between
                   1687: # courses.
                   1688: 
1.538     raeburn  1689:         unless ($is_map{$suffix}) {
                   1690:             my $newidx;
1.492     raeburn  1691: # Now insert the URL at the bottom
1.538     raeburn  1692:             $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url));
                   1693:             if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(.+)$}) {
                   1694:                 my $relpath = $1;
                   1695:                 if ($relpath ne '') {
                   1696:                     my ($prefix,$subdir,$rem) = ($relpath =~ m{^(default|\d+)/(\d+)/(.+)$});
                   1697:                     my ($newloc,$newdocsdir) = ($folder =~ /^(default|supplemental)_?(\d*)/);
                   1698:                     my $newprefix = $newloc;
                   1699:                     if ($newloc eq 'default') {
                   1700:                         $newprefix = 'docs';
                   1701:                     }
                   1702:                     if ($newdocsdir eq '') {
                   1703:                         $newdocsdir = 'default';
                   1704:                     }
                   1705:                     if (($prefixchg{$suffix}) || 
                   1706:                         ($srcdom{$suffix} ne $coursedom) || 
                   1707:                         ($srcnum{$suffix} ne $coursenum) ||
                   1708:                         ($env{'form.docs.markedcopy_options_'.$suffix} ne 'move')) {
                   1709:                         my $newpath = "$newprefix/$newdocsdir/$newidx/$rem";
                   1710:                         $url =
                   1711:                             &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath,
                   1712:                                                                &Apache::lonnet::getfile($oldurl));
                   1713:                         if ($url eq '/adm/notfound.html') {
                   1714:                             $msgs{$suffix} = &mt('Paste failed: an error occurred saving the file.');
                   1715:                             next;
                   1716:                         } else {
                   1717:                             my ($newsubpath) = ($newpath =~ m{^(.*/)[^/]*$});
                   1718:                             $newsubpath =~ s{/+$}{/};
                   1719:                             $docmoves{$oldurl} = $newsubpath;
                   1720:                         }
1.491     raeburn  1721:                     }
                   1722:                 }
                   1723:             }
1.538     raeburn  1724:             $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
                   1725:                                               ':'.$ext.':normal:res';
                   1726:             push(@LONCAPA::map::order,$newidx);
                   1727: # Store the result
                   1728:             my ($errtext,$fatal) =
                   1729:                 &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
                   1730:             if ($fatal) {
                   1731:                 $save_err .= $errtext;
                   1732:                 $allresult = 'fail';
                   1733:             }
1.488     raeburn  1734:         }
1.538     raeburn  1735: 
1.492     raeburn  1736: # Apply any changes to maps, or copy dependencies for uploaded HTML pages 
1.538     raeburn  1737:         unless ($allresult eq 'fail') {
                   1738:             my %updated = (
                   1739:                             rewrites      => \%rewrites,
                   1740:                             zombies       => \%zombies,
                   1741:                             removefrommap => \%removefrommap,
                   1742:                             removeparam   => \%removeparam,
                   1743:                             dbcopies      => \%dbcopies,
                   1744:                             retitles      => \%retitles,
                   1745:                           );
                   1746:             my %info = (
                   1747:                            newsubdir => \%newsubdir,
                   1748:                            params    => \%params,
                   1749:                        );
                   1750:             if ($prefixchg{$suffix}) {
                   1751:                 $info{'before'} = $before{$prefixchg{$suffix}};
                   1752:                 $info{'after'} = $after{$prefixchg{$suffix}};
                   1753:             }
                   1754:             my %moves = (
                   1755:                            copies   => \%copies,
                   1756:                            docmoves => \%docmoves,
                   1757:                            mapmoves => \%mapmoves,
                   1758:                         );
                   1759:             (my $result,$msgs{$suffix},my $lockerror) =
                   1760:                 &apply_fixups($folder,$is_map{$suffix},$coursedom,$coursenum,$errors,
                   1761:                               \%updated,\%info,\%moves,$prefixchg{$suffix},$oldurl,
                   1762:                               $url,'paste');
                   1763:             $lockerrors .= $lockerror;
                   1764:             if ($result eq 'ok') {
                   1765:                 if ($is_map{$suffix}) {
                   1766:                     my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                   1767:                                                     $folder.'.'.$container);
                   1768:                     if ($fatal) {
                   1769:                         $allresult = 'failread';
                   1770:                     } else {
                   1771:                         if ($#LONCAPA::map::order<1) {
                   1772:                             my $idx=&LONCAPA::map::getresidx();
                   1773:                             if ($idx<=0) { $idx=1; }
                   1774:                             $LONCAPA::map::order[0]=$idx;
                   1775:                             $LONCAPA::map::resources[$idx]='';
                   1776:                         }
                   1777:                         my $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url));
                   1778:                         $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
                   1779:                                                           ':'.$ext.':normal:res';
                   1780:                         push(@LONCAPA::map::order,$newidx);
1.492     raeburn  1781: 
                   1782: # Store the result
1.538     raeburn  1783:                         my ($errtext,$fatal) = 
                   1784:                             &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
                   1785:                         if ($fatal) {
                   1786:                             $save_err .= $errtext;
                   1787:                             $allresult = 'failstore';
                   1788:                         }
                   1789:                     } 
                   1790:                 }
                   1791:                 if ($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') {
                   1792:                      push(@toclear,$suffix);
                   1793:                 }
                   1794:             }
1.492     raeburn  1795:         }
                   1796:     }
1.538     raeburn  1797:     &clear_from_buffer(\@toclear,\@currpaste);
                   1798:     my $msgsarray;
                   1799:     foreach my $suffix (keys(%msgs)) {
                   1800:          if (ref($msgs{$suffix}) eq 'ARRAY') {
                   1801:              $msgsarray .= join(',',@{$msgs{$suffix}});
                   1802:          }
                   1803:     }
                   1804:     return ($allresult,$save_err,$msgsarray,$lockerrors);
                   1805: }
1.533     raeburn  1806: 
1.538     raeburn  1807: sub do_buffer_empty {
                   1808:     my @currpaste = split(/,/,$env{'docs.markedcopies'});
                   1809:     if (@currpaste == 0) {
                   1810:         return &mt('Clipboard is already empty');
                   1811:     }
                   1812:     my @toclear = &Apache::loncommon::get_env_multiple('form.pasting');
                   1813:     if (@toclear == 0) {
                   1814:         return &mt('Nothing selected to clear from clipboard');
                   1815:     }
                   1816:     my $numdel = &clear_from_buffer(\@toclear,\@currpaste);
                   1817:     if ($numdel) {
                   1818:         return &mt('[quant,_1,item] cleared from clipboard',$numdel);
                   1819:     } else {
                   1820:         return &mt('Clipboard unchanged');
1.492     raeburn  1821:     }
1.538     raeburn  1822:     return;
                   1823: }
                   1824: 
                   1825: sub clear_from_buffer {
                   1826:     my ($toclear,$currpaste) = @_;
                   1827:     return unless ((ref($toclear) eq 'ARRAY') && (ref($currpaste) eq 'ARRAY'));
                   1828:     my %pastebuffer;
                   1829:     map { $pastebuffer{$_} = 1; } @{$currpaste};
                   1830:     my $numdel = 0;
                   1831:     foreach my $suffix (@{$toclear}) {
                   1832:         next if ($suffix =~ /\D/);
                   1833:         next unless (exists($pastebuffer{$suffix}));
                   1834:         my $regexp = 'docs.markedcopy_[a-z]+_'.$suffix;
                   1835:         if (&Apache::lonnet::delenv($regexp,1) eq 'ok') {
                   1836:             delete($pastebuffer{$suffix});
                   1837:             $numdel ++;
                   1838:         }
                   1839:     }
                   1840:     my $newbuffer = join(',',sort(keys(%pastebuffer)));
                   1841:     &Apache::lonnet::appenv({'docs.markedcopies' => $newbuffer});
                   1842:     return $numdel;
1.492     raeburn  1843: }
                   1844: 
                   1845: sub get_newmap_url {
                   1846:     my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,
                   1847:         $titleref,$allmaps,$newurls) = @_;
                   1848:     my $newurl;
                   1849:     if ($url=~ m{^/uploaded/}) {
                   1850:         $$titleref=&mt('Copy of').' '.$$titleref;
                   1851:     }
                   1852:     my $now = time;
                   1853:     my $suffix=$$.int(rand(100)).$now;
                   1854:     my ($oldid,$ext) = ($url=~/^(.+)\.(\w+)$/);
                   1855:     if ($oldid =~ m{^(/uploaded/$match_domain/$match_courseid/)(\D+)(\d+)$}) {
                   1856:         my $path = $1;
                   1857:         my $prefix = $2;
                   1858:         my $ancestor = $3;
                   1859:         if (length($ancestor) > 10) {
                   1860:             $ancestor = substr($ancestor,-10,10);
                   1861:         }
                   1862:         my $newid;
                   1863:         if ($prefixchg) {
                   1864:             if ($folder =~ /^supplemental/) {
                   1865:                 $prefix =~ s/^default/supplemental/;
                   1866:             } else {
                   1867:                 $prefix =~ s/^supplemental/default/;
                   1868:             }
                   1869:         }
                   1870:         if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) {
                   1871:             $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext;
                   1872:         } else {
                   1873:             $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$now.'.'.$ext;
                   1874:         }
                   1875:         my $counter = 0;
                   1876:         my $is_unique = &uniqueness_check($newurl);
                   1877:         if ($folder =~ /^default/) {
                   1878:             if ($allmaps->{$newurl}) {
                   1879:                 $is_unique = 0;
                   1880:             }
                   1881:         }
                   1882:         while ((!$is_unique || $allmaps->{$newurl} || $newurls->{$newurl}) && ($counter < 100)) {
                   1883:             $counter ++;
                   1884:             $suffix ++;
                   1885:             if (($srcdom eq $coursedom) && ($srcnum eq $coursenum)) {
                   1886:                 $newurl = $path.$prefix.$ancestor.$suffix.'.'.$ext;
                   1887:             } else {
                   1888:                 $newurl = "/uploaded/$coursedom/$coursenum/$prefix".$ancestor.$suffix.'.'.$ext;
                   1889:             }
                   1890:             $is_unique = &uniqueness_check($newurl);
                   1891:         }
                   1892:         if ($is_unique) {
                   1893:             $newurls->{$newurl} = 1;
                   1894:         } else {
                   1895:             if ($url=~/\.page$/) {
                   1896:                 return (undef,&mt('Paste failed: an error occurred creating a unique URL for the composite page'));
                   1897:             } else {
                   1898:                 return (undef,&mt('Paste failed: an error occurred creating a unique URL for the folder'));
                   1899:             }
                   1900:         }
1.329     droeschl 1901:     }
1.492     raeburn  1902:     return ($newurl);
1.329     droeschl 1903: }
                   1904: 
1.488     raeburn  1905: sub dbcopy {
1.533     raeburn  1906:     my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
                   1907:     my ($url,$result,$errtext);
1.564     raeburn  1908:     $url = $dbref->{'src'};
1.533     raeburn  1909:     if (ref($dbref) eq 'HASH') {
                   1910:         if ($url =~ m{/(smppg|bulletinboard)$}) {
                   1911:             my $prefix = $1;
                   1912:             if (($dbref->{'cdom'} =~ /^$match_domain$/) && 
                   1913:                 ($dbref->{'cnum'} =~ /^$match_courseid$/)) {
                   1914:                 my $db_name;
                   1915:                 my $marker = (split(m{/},$url))[4];
                   1916:                 $marker=~s/\D//g;
                   1917:                 if ($dbref->{'src'} =~ m{/smppg$}) {
                   1918:                     $db_name =
                   1919:                         &Apache::lonsimplepage::get_db_name($url,$marker,
                   1920:                                                             $dbref->{'cdom'},
                   1921:                                                             $dbref->{'cnum'});
                   1922:                 } else {
                   1923:                     $db_name = 'bulletinpage_'.$marker;
                   1924:                 }
                   1925:                 my ($suffix,$freedlock,$error) =
                   1926:                     &Apache::lonnet::get_timebased_id($prefix,'num','templated',
                   1927:                                                       $coursedom,$coursenum,
                   1928:                                                       'concat');
                   1929:                 if (!$suffix) {
                   1930:                     if ($prefix eq 'smppg') {
                   1931:                         $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url);
                   1932:                     } else {
1.565     bisitz   1933:                         $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a discussion board [_1].',$url);
1.533     raeburn  1934:                     }
                   1935:                     if ($error) {
                   1936:                         $errtext .= '<br />'.$error;
                   1937:                     }
                   1938:                 } else {
                   1939:                     #need to copy the db contents to a new one.
                   1940:                     my %contents=&Apache::lonnet::dump($db_name,
                   1941:                                                        $dbref->{'cdom'},
                   1942:                                                        $dbref->{'cnum'});
                   1943:                     if (exists($contents{'uploaded.photourl'})) {
                   1944:                         my $photo = $contents{'uploaded.photourl'};
                   1945:                         my ($subdir,$fname) =
                   1946:                             ($photo =~ m{^/uploaded/$match_domain/$match_courseid/+(bulletin|simplepage)/(?:|\d+/)([^/]+)$});
                   1947:                         my $newphoto; 
                   1948:                         if ($fname ne '') {
                   1949:                             my $content = &Apache::lonnet::getfile($photo);
                   1950:                             unless ($content eq '-1') {
                   1951:                                 $env{'form.'.$suffix.'.photourl'} = $content;
                   1952:                                 $newphoto = 
                   1953:                                     &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.photourl',"$subdir/$suffix/$fname");
                   1954:                                 delete($env{'form.'.$suffix.'.photourl'});
                   1955:                             }
                   1956:                         }
                   1957:                         if ($newphoto =~ m{^/uploaded/}) {
                   1958:                             $contents{'uploaded.photourl'} = $newphoto;
                   1959:                         }
                   1960:                     }
                   1961:                     $db_name =~ s{_\d*$ }{_$suffix}x;
                   1962:                     $result=&Apache::lonnet::put($db_name,\%contents,
                   1963:                                                  $coursedom,$coursenum);
                   1964:                     if ($result eq 'ok') {
                   1965:                         $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x;
                   1966:                     }
                   1967:                 }
                   1968:                 if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
1.559     raeburn  1969:                     $lockerrorsref->{$prefix} =
1.533     raeburn  1970:                         '<div class="LC_error">'.
                   1971:                         &mt('There was a problem removing a lockfile.');
                   1972:                     if ($prefix eq 'smppg') {
1.560     raeburn  1973:                         $lockerrorsref->{$prefix} .=
1.559     raeburn  1974:                             ' '.&mt('This will prevent creation of additional simple pages in this course.');
1.533     raeburn  1975:                     } else {
1.565     bisitz   1976:                         $lockerrorsref->{$prefix} .= ' '.&mt('This will prevent creation of additional discussion boards in this course.');
1.533     raeburn  1977:                     }
1.560     raeburn  1978:                     $lockerrorsref->{$prefix} .= ' '.&mt('Please contact the [_1]helpdesk[_2] for assistance.',
                   1979:                                                      '<a href="/adm/helpdesk" target="_helpdesk">','</a>').
                   1980:                                                  '</div>';
1.533     raeburn  1981:                 }
                   1982:             }
                   1983:         } elsif ($url =~ m{/syllabus$}) {
                   1984:             if (($dbref->{'cdom'} =~ /^$match_domain$/) &&
                   1985:                 ($dbref->{'cnum'} =~ /^$match_courseid$/)) {
                   1986:                 if (($dbref->{'cdom'} ne $coursedom) ||
                   1987:                     ($dbref->{'cnum'} ne $coursenum)) {
                   1988:                     my %contents=&Apache::lonnet::dump('syllabus',
                   1989:                                                        $dbref->{'cdom'},
                   1990:                                                        $dbref->{'cnum'});
                   1991:                     $result=&Apache::lonnet::put('syllabus',\%contents,
                   1992:                                                  $coursedom,$coursenum);
                   1993:                 }
                   1994:             }
1.488     raeburn  1995:         }
                   1996:     }
1.533     raeburn  1997:     return ($url,$result,$errtext);
1.488     raeburn  1998: }
                   1999: 
1.329     droeschl 2000: sub uniqueness_check {
                   2001:     my ($newurl) = @_;
                   2002:     my $unique = 1;
                   2003:     foreach my $res (@LONCAPA::map::order) {
                   2004:         my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
                   2005:         $url=&LONCAPA::map::qtescape($url);
                   2006:         if ($newurl eq $url) {
                   2007:             $unique = 0;
1.344     bisitz   2008:             last;
1.329     droeschl 2009:         }
                   2010:     }
                   2011:     return $unique;
                   2012: }
                   2013: 
1.488     raeburn  2014: sub contained_map_check {
1.492     raeburn  2015:     my ($url,$folder,$removefrommap,$removeparam,$addedmaps,$hierarchy,$titles,
                   2016:         $allmaps) = @_;
1.488     raeburn  2017:     my $content = &Apache::lonnet::getfile($url);
                   2018:     unless ($content eq '-1') {
                   2019:         my $parser = HTML::TokeParser->new(\$content);
                   2020:         $parser->attr_encoded(1);
                   2021:         while (my $token = $parser->get_token) {
                   2022:             next if ($token->[0] ne 'S');
                   2023:             if ($token->[1] eq 'resource') {
                   2024:                 next if ($token->[2]->{'type'} eq 'zombie');
                   2025:                 my $ressrc = $token->[2]->{'src'};
                   2026:                 if ($folder =~ /^supplemental/) {
                   2027:                     unless (&supp_pasteable($ressrc)) {
1.492     raeburn  2028:                         $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
1.488     raeburn  2029:                         next;
                   2030:                     }
                   2031:                 }
1.492     raeburn  2032:                 if ($ressrc =~ m{^/(res|uploaded)/.+\.(sequence|page)$}) {
                   2033:                     if ($1 eq 'uploaded') {
                   2034:                         $hierarchy->{$url}{$token->[2]->{'id'}} = $ressrc;
                   2035:                         $titles->{$url}{$token->[2]->{'id'}} = $token->[2]->{'title'};
1.488     raeburn  2036:                     } else {
1.492     raeburn  2037:                         if ($allmaps->{$ressrc}) {
1.529     raeburn  2038:                             $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
1.492     raeburn  2039:                         } elsif (ref($addedmaps->{$ressrc}) eq 'ARRAY') {
                   2040:                             $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
                   2041:                         } else {
                   2042:                             $addedmaps->{$ressrc} = [$url];
                   2043:                         }
1.488     raeburn  2044:                     }
1.492     raeburn  2045:                     &contained_map_check($ressrc,$folder,$removefrommap,$removeparam,
                   2046:                                          $addedmaps,$hierarchy,$titles,$allmaps);
1.488     raeburn  2047:                 }
1.492     raeburn  2048:             } elsif ($token->[1] eq 'param') {
1.488     raeburn  2049:                 if ($folder =~ /^supplemental/) {
1.492     raeburn  2050:                     if (ref($removeparam->{$url}{$token->[2]->{'to'}}) eq 'ARRAY') {
                   2051:                         push(@{$removeparam->{$url}{$token->[2]->{'to'}}},$token->[2]->{'name'});
                   2052:                     } else {
                   2053:                         $removeparam->{$url}{$token->[2]->{'to'}} = [$token->[2]->{'name'}]; 
                   2054:                     }
1.488     raeburn  2055:                 }
                   2056:             }
                   2057:         }
                   2058:     }
                   2059:     return;
                   2060: }
                   2061: 
                   2062: sub url_paste_fixups {
1.533     raeburn  2063:     my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps,
                   2064:         $rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves,
                   2065:         $mapchanges,$tomove,$newsubdir,$newurls) = @_;
1.491     raeburn  2066:     my $checktitle;
                   2067:     if (($prefixchg) &&
1.492     raeburn  2068:         ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) {
1.491     raeburn  2069:         $checktitle = 1;
                   2070:     }
1.492     raeburn  2071:     my $skip;
                   2072:     if ($oldurl =~ m{^\Q/uploaded/$cdom/$cnum/\E(default|supplemental)(_?\d*)\.(?:page|sequence)$}) {
                   2073:         my $mapid = $1.$2;
                   2074:         if ($tomove->{$mapid}) {
                   2075:             $skip = 1;
                   2076:         }
                   2077:     }
1.491     raeburn  2078:     my $file = &Apache::lonnet::getfile($oldurl);
1.488     raeburn  2079:     return if ($file eq '-1');
                   2080:     my $parser = HTML::TokeParser->new(\$file);
                   2081:     $parser->attr_encoded(1);
1.491     raeburn  2082:     my $changed = 0;
1.488     raeburn  2083:     while (my $token = $parser->get_token) {
                   2084:         next if ($token->[0] ne 'S');
                   2085:         if ($token->[1] eq 'resource') {
                   2086:             my $ressrc = $token->[2]->{'src'};
                   2087:             next if ($ressrc eq '');
1.491     raeburn  2088:             my $id = $token->[2]->{'id'};
1.492     raeburn  2089:             my $title = $token->[2]->{'title'};
1.491     raeburn  2090:             if ($checktitle) {
                   2091:                 if ($title =~ m{\d+\Q___&amp;&amp;&amp;___\E$match_username\Q___&amp;&amp;&amp;___\E$match_domain\Q___&amp;&amp;&amp;___\E(.+)$}) {
1.532     raeburn  2092:                     $retitles->{$oldurl}{$id} = $ressrc;
1.491     raeburn  2093:                 }
                   2094:             }
1.488     raeburn  2095:             next if ($token->[2]->{'type'} eq 'external');
                   2096:             if ($token->[2]->{'type'} eq 'zombie') {
1.492     raeburn  2097:                 next if ($skip);  
1.532     raeburn  2098:                 $zombies->{$oldurl}{$id} = $ressrc;
1.491     raeburn  2099:                 $changed = 1;
                   2100:             } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
1.492     raeburn  2101:                 my $srcdom = $1;
                   2102:                 my $srcnum = $2;
1.488     raeburn  2103:                 my $rem = $3;
1.492     raeburn  2104:                 my $newurl;
                   2105:                 my $mapname;
                   2106:                 if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) {
                   2107:                     my $prefix = $1;
                   2108:                     $mapname = $prefix.$2;
                   2109:                     if ($tomove->{$mapname}) {
1.533     raeburn  2110:                         &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,
                   2111:                                           $srcdom,$srcnum,$allmaps,$rewrites,
                   2112:                                           $retitles,$copies,$dbcopies,$zombies,
                   2113:                                           $params,$mapmoves,$mapchanges,$tomove,
                   2114:                                           $newsubdir,$newurls);
1.492     raeburn  2115:                         next;
                   2116:                     } else {
                   2117:                         ($newurl,my $error) =
                   2118:                             &get_newmap_url($ressrc,$folder,$prefixchg,$cdom,$cnum,
                   2119:                                             $srcdom,$srcnum,\$title,$allmaps,$newurls);
                   2120:                         if ($newurl =~ /(?:default|supplemental)_(\d+)\.(?:sequence|page)$/) {
                   2121:                             $newsubdir->{$ressrc} = $1;
                   2122:                         }
                   2123:                         if ($error) {
                   2124:                             next;
                   2125:                         }
                   2126:                     }
                   2127:                 }
                   2128:                 if (($srcdom ne $cdom) || ($srcnum ne $cnum) || ($prefixchg) ||
                   2129:                     ($mapchanges->{$oldurl}) || (($newurl ne '') && ($newurl ne $oldurl))) {
                   2130:                    
1.488     raeburn  2131:                     if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) {
1.532     raeburn  2132:                         $rewrites->{$oldurl}{$id} = $ressrc;
1.491     raeburn  2133:                         $mapchanges->{$ressrc} = 1;
1.533     raeburn  2134:                         unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,
                   2135:                                                   $cnum,$srcdom,$srcnum,$allmaps,
                   2136:                                                   $rewrites,$retitles,$copies,$dbcopies,
                   2137:                                                   $zombies,$params,$mapmoves,$mapchanges,
                   2138:                                                   $tomove,$newsubdir,$newurls)) {
1.491     raeburn  2139:                             $mapmoves->{$ressrc} = 1;
                   2140:                         }
                   2141:                         $changed = 1;
1.488     raeburn  2142:                     } else {
1.532     raeburn  2143:                         $rewrites->{$oldurl}{$id} = $ressrc;
1.488     raeburn  2144:                         $copies->{$oldurl}{$ressrc} = $id;
1.491     raeburn  2145:                         $changed = 1;
1.488     raeburn  2146:                     }
                   2147:                 }
1.533     raeburn  2148:             } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/.+$}) {
                   2149:                 next if ($skip);
1.492     raeburn  2150:                 my $srcdom = $1;
                   2151:                 my $srcnum = $2;
                   2152:                 if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {
1.532     raeburn  2153:                     $rewrites->{$oldurl}{$id} = $ressrc;
1.533     raeburn  2154:                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
                   2155:                     $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
                   2156:                     $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;
                   2157:                     $changed = 1;
                   2158:                 }
                   2159:             } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) {
                   2160:                 if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) ||
                   2161:                     ($env{'form.docs.markedcopy_options'} ne 'move')) {
                   2162:                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
                   2163:                     $dbcopies->{$oldurl}{$id}{'cdom'} = $fromcdom;
                   2164:                     $dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum;
1.491     raeburn  2165:                     $changed = 1;
1.488     raeburn  2166:                 }
                   2167:             } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) {
1.492     raeburn  2168:                 next if ($skip);
                   2169:                 my $srcdom = $1;
                   2170:                 my $srcnum = $2;
                   2171:                 if (($srcdom ne $cdom) || ($srcnum ne $cnum)) {
1.533     raeburn  2172:                     $dbcopies->{$oldurl}{$id}{'src'} = $ressrc;
                   2173:                     $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom;
                   2174:                     $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum;
1.491     raeburn  2175:                     $changed = 1;
1.488     raeburn  2176:                 }
                   2177:             }
                   2178:         } elsif ($token->[1] eq 'param') {
1.492     raeburn  2179:             next if ($skip);
1.488     raeburn  2180:             my $to = $token->[2]->{'to'}; 
                   2181:             if ($to ne '') {
                   2182:                 if (ref($params->{$oldurl}{$to}) eq 'ARRAY') {
1.492     raeburn  2183:                     push(@{$params->{$oldurl}{$to}},$token->[2]->{'name'});
1.488     raeburn  2184:                 } else {
                   2185:                     @{$params->{$oldurl}{$to}} = ($token->[2]->{'name'});
                   2186:                 }
                   2187:             }
                   2188:         }
                   2189:     }
1.491     raeburn  2190:     return $changed;
1.488     raeburn  2191: }
                   2192: 
                   2193: sub apply_fixups {
1.529     raeburn  2194:     my ($folder,$is_map,$cdom,$cnum,$errors,$updated,$info,$moves,$prefixchg,
                   2195:         $oldurl,$url,$caller) = @_;
                   2196:     my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
1.533     raeburn  2197:         %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs,
                   2198:         %lockerrors,$lockmsg);
1.529     raeburn  2199:     if (ref($updated) eq 'HASH') {
                   2200:         if (ref($updated->{'rewrites'}) eq 'HASH') {
                   2201:             %rewrites = %{$updated->{'rewrites'}};
                   2202:         }
                   2203:         if (ref($updated->{'zombies'}) eq 'HASH') {
                   2204:             %zombies = %{$updated->{'zombies'}};
                   2205:         }
                   2206:         if (ref($updated->{'removefrommap'}) eq 'HASH') {
                   2207:             %removefrommap = %{$updated->{'removefrommap'}};
                   2208:         }
                   2209:         if (ref($updated->{'removeparam'}) eq 'HASH') {
                   2210:             %removeparam = %{$updated->{'removeparam'}};
                   2211:         }
                   2212:         if (ref($updated->{'dbcopies'}) eq 'HASH') {
                   2213:             %dbcopies = %{$updated->{'dbcopies'}};
                   2214:         }
                   2215:         if (ref($updated->{'retitles'}) eq 'HASH') {
                   2216:             %retitles = %{$updated->{'retitles'}};
                   2217:         }
                   2218:     }
                   2219:     if (ref($info) eq 'HASH') {
                   2220:         if (ref($info->{'newsubdir'}) eq 'HASH') {
                   2221:             %newsubdir = %{$info->{'newsubdir'}};
                   2222:         }
                   2223:         if (ref($info->{'params'}) eq 'HASH') {
                   2224:             %params = %{$info->{'params'}};
                   2225:         }
                   2226:         if (ref($info->{'before'}) eq 'HASH') {
                   2227:             %before = %{$info->{'before'}};
                   2228:         }
                   2229:         if (ref($info->{'after'}) eq 'HASH') {
                   2230:             %after = %{$info->{'after'}};
                   2231:         }
                   2232:     }
                   2233:     if (ref($moves) eq 'HASH') {
                   2234:         if (ref($moves->{'copies'}) eq 'HASH') {
                   2235:             %copies = %{$moves->{'copies'}};
                   2236:         }
                   2237:         if (ref($moves->{'docmoves'}) eq 'HASH') {
                   2238:             %docmoves = %{$moves->{'docmoves'}};
                   2239:         }
                   2240:         if (ref($moves->{'mapmoves'}) eq 'HASH') {
                   2241:             %mapmoves = %{$moves->{'mapmoves'}};
                   2242:         }
                   2243:     }
                   2244:     foreach my $key (keys(%copies),keys(%docmoves)) {
1.491     raeburn  2245:         my @allcopies;
1.529     raeburn  2246:         if (exists($copies{$key})) {
                   2247:             if (ref($copies{$key}) eq 'HASH') {
                   2248:                 my %added;
                   2249:                 foreach my $innerkey (keys(%{$copies{$key}})) {
                   2250:                     if (($innerkey ne '') && (!$added{$innerkey})) {
                   2251:                         push(@allcopies,$innerkey);
                   2252:                         $added{$innerkey} = 1;
                   2253:                     }
1.491     raeburn  2254:                 }
1.529     raeburn  2255:                 undef(%added);
1.491     raeburn  2256:             }
                   2257:         }
                   2258:         if ($key eq $oldurl) {
1.529     raeburn  2259:             if ((exists($docmoves{$key}))) {
1.532     raeburn  2260:                 unless (grep(/^\Q$oldurl\E$/,@allcopies)) {
1.491     raeburn  2261:                     push(@allcopies,$oldurl);
                   2262:                 }
                   2263:             }
                   2264:         }
                   2265:         if (@allcopies > 0) {
                   2266:             foreach my $item (@allcopies) {
1.492     raeburn  2267:                 my ($relpath,$oldsubdir,$fname) = 
                   2268:                     ($item =~ m{^(/uploaded/$match_domain/$match_courseid/(?:docs|supplemental)/(default|\d+)/.*/)([^/]+)$});
1.491     raeburn  2269:                 if ($fname ne '') {
                   2270:                     my $content = &Apache::lonnet::getfile($item);
                   2271:                     unless ($content eq '-1') {
                   2272:                         my $storefn;
1.529     raeburn  2273:                         if (($key eq $oldurl) && (exists($docmoves{$key}))) {
                   2274:                             $storefn = $docmoves{$key};
1.491     raeburn  2275:                         } else {
                   2276:                             $storefn = $relpath;
                   2277:                             $storefn =~s{^/uploaded/$match_domain/$match_courseid/}{};
1.529     raeburn  2278:                             if ($prefixchg && $before{'doc'} && $after{'doc'}) {
                   2279:                                 $storefn =~ s/^\Q$before{'doc'}\E/$after{'doc'}/;
1.491     raeburn  2280:                             }
1.529     raeburn  2281:                             if ($newsubdir{$key}) {
1.532     raeburn  2282:                                 $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir{$key}/#;
1.491     raeburn  2283:                             }
                   2284:                         }
                   2285:                         &copy_dependencies($item,$storefn,$relpath,$errors,\$content);
                   2286:                         my $copyurl = 
                   2287:                             &Apache::lonclonecourse::writefile($env{'request.course.id'},
                   2288:                                                                $storefn.$fname,$content);
                   2289:                         if ($copyurl eq '/adm/notfound.html') {
1.529     raeburn  2290:                             if (exists($docmoves{$oldurl})) {
1.491     raeburn  2291:                                 return &mt('Paste failed: an error occurred copying the file.');
                   2292:                             } elsif (ref($errors) eq 'HASH') {
                   2293:                                 $errors->{$item} = 1;
1.489     raeburn  2294:                             }
                   2295:                         }
1.488     raeburn  2296:                     }
                   2297:                 }
1.491     raeburn  2298:             }
                   2299:         }
                   2300:     }
1.529     raeburn  2301:     foreach my $key (keys(%mapmoves)) {
1.491     raeburn  2302:         my $storefn=$key;
                   2303:         $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
1.529     raeburn  2304:         if ($prefixchg && $before{'map'} && $after{'map'}) {
                   2305:             $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/;
1.491     raeburn  2306:         }
1.529     raeburn  2307:         if ($newsubdir{$key}) {
                   2308:             $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
1.492     raeburn  2309:         }
1.491     raeburn  2310:         my $mapcontent = &Apache::lonnet::getfile($key);
                   2311:         if ($mapcontent eq '-1') {
                   2312:             if (ref($errors) eq 'HASH') {
                   2313:                 $errors->{$key} = 1;
                   2314:             }
                   2315:         } else {
                   2316:             my $newmap =
                   2317:                 &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,
                   2318:                                                    $mapcontent);
                   2319:             if ($newmap eq '/adm/notfound.html') {
                   2320:                 if (ref($errors) eq 'HASH') {
                   2321:                     $errors->{$key} = 1;
1.489     raeburn  2322:                 }
1.488     raeburn  2323:             }
                   2324:         }
                   2325:     }
1.491     raeburn  2326:     my %updates;
                   2327:     if ($is_map) {
1.529     raeburn  2328:         if (ref($updated) eq 'HASH') {
                   2329:             foreach my $type (keys(%{$updated})) {
                   2330:                 if (ref($updated->{$type}) eq 'HASH') {
                   2331:                     foreach my $key (keys(%{$updated->{$type}})) {
                   2332:                         $updates{$key} = 1;
                   2333:                     }
                   2334:                 }
                   2335:             }
1.491     raeburn  2336:         }
                   2337:         foreach my $key (keys(%updates)) {
1.492     raeburn  2338:             my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
1.529     raeburn  2339:             if (ref($rewrites{$key}) eq 'HASH') {
                   2340:                 %torewrite = %{$rewrites{$key}};
1.491     raeburn  2341:             }
1.529     raeburn  2342:             if (ref($retitles{$key}) eq 'HASH') {
                   2343:                 %toretitle = %{$retitles{$key}};
1.491     raeburn  2344:             }
1.529     raeburn  2345:             if (ref($removefrommap{$key}) eq 'HASH') {
                   2346:                 %toremove = %{$removefrommap{$key}};
1.491     raeburn  2347:             }
1.529     raeburn  2348:             if (ref($removeparam{$key}) eq 'HASH') {
                   2349:                 %remparam = %{$removeparam{$key}};
1.492     raeburn  2350:             }
1.529     raeburn  2351:             if (ref($zombies{$key}) eq 'HASH') {
                   2352:                 %zombie = %{$zombies{$key}};
1.491     raeburn  2353:             }
1.529     raeburn  2354:             if (ref($dbcopies{$key}) eq 'HASH') {
1.533     raeburn  2355:                 foreach my $idx (keys(%{$dbcopies{$key}})) {
                   2356:                     if (ref($dbcopies{$key}{$idx}) eq 'HASH') {
                   2357:                         my ($newurl,$result,$errtext) =
                   2358:                             &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors);
                   2359:                         if ($result eq 'ok') {
                   2360:                             $newdb{$idx} = $newurl;
                   2361:                         } elsif (ref($errors) eq 'HASH') {
                   2362:                             $errors->{$key} = 1;
                   2363:                         }
                   2364:                         push(@msgs,$errtext);
                   2365:                     }
1.491     raeburn  2366:                 }
                   2367:             }
1.529     raeburn  2368:             if (ref($params{$key}) eq 'HASH') {
                   2369:                 %currparam = %{$params{$key}};
1.492     raeburn  2370:             }
                   2371:             my ($errtext,$fatal) = &LONCAPA::map::mapread($key);
                   2372:             if ($fatal) {
1.533     raeburn  2373:                 return ($errtext);
1.492     raeburn  2374:             }
                   2375:             for (my $i=0; $i<@LONCAPA::map::zombies; $i++) {
                   2376:                 if (defined($LONCAPA::map::zombies[$i])) {
                   2377:                     my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::zombies[$i]);
1.532     raeburn  2378:                     if ($zombie{$i} eq $src) {
1.492     raeburn  2379:                         undef($LONCAPA::map::zombies[$i]);
                   2380:                     }
                   2381:                 }
                   2382:             }
1.529     raeburn  2383:             for (my $i=0; $i<@LONCAPA::map::order; $i++) {
                   2384:                 my $idx = $LONCAPA::map::order[$i];
                   2385:                 if (defined($LONCAPA::map::resources[$idx])) {
1.492     raeburn  2386:                     my $changed;
1.529     raeburn  2387:                     my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$idx]);
1.538     raeburn  2388:                     if ((exists($toremove{$idx})) && 
                   2389:                         ($toremove{$idx} eq &LONCAPA::map::qtescape($src))) {
1.492     raeburn  2390:                         splice(@LONCAPA::map::order,$i,1);
1.529     raeburn  2391:                         if (ref($currparam{$idx}) eq 'ARRAY') {
                   2392:                             foreach my $name (@{$currparam{$idx}}) {
                   2393:                                 &LONCAPA::map::delparameter($idx,'parameter_'.$name);
1.492     raeburn  2394:                             }
                   2395:                         }
                   2396:                         next;
                   2397:                     }
                   2398:                     my $origsrc = $src;
1.532     raeburn  2399:                     if ((exists($toretitle{$idx})) && ($toretitle{$idx} eq $src)) {
1.492     raeburn  2400:                         if ($title =~ m{^\d+\Q___&amp;&amp;&amp;___\E$match_username\Q___&amp;&amp;&amp;___\E$match_domain\Q___&amp;&amp;&amp;___\E(.+)$}) {
                   2401:                             $changed = 1;
1.491     raeburn  2402:                         }
1.492     raeburn  2403:                     }
1.532     raeburn  2404:                     if ((exists($torewrite{$idx})) && ($torewrite{$idx} eq $src)) {
1.492     raeburn  2405:                         $src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/};
                   2406:                         if ($origsrc =~ m{^/uploaded/}) {
1.529     raeburn  2407:                             if ($prefixchg && $before{'map'} && $after{'map'}) {
1.492     raeburn  2408:                                 if ($src =~ /\.(page|sequence)$/) {
1.529     raeburn  2409:                                     $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'map'}\E#$1$after{'map'}#;
1.492     raeburn  2410:                                 } else {
1.529     raeburn  2411:                                     $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'doc'}\E#$1$after{'doc'}#;
1.488     raeburn  2412:                                 }
1.491     raeburn  2413:                             }
1.532     raeburn  2414:                             if ($origsrc =~ /\.(page|sequence)$/) {
                   2415:                                 if ($newsubdir{$origsrc}) {
1.529     raeburn  2416:                                     $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir{$origsrc}#;
1.491     raeburn  2417:                                 }
1.532     raeburn  2418:                             } elsif ($newsubdir{$key}) {
                   2419:                                 $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir{$key}#;
1.488     raeburn  2420:                             }
                   2421:                         }
1.492     raeburn  2422:                         $changed = 1;
1.533     raeburn  2423:                     } elsif ($newdb{$idx} ne '') {
                   2424:                         $src = $newdb{$idx};
1.492     raeburn  2425:                         $changed = 1;
                   2426:                     }
                   2427:                     if ($changed) {
1.538     raeburn  2428:                         $LONCAPA::map::resources[$idx] = join(':',($title,&LONCAPA::map::qtunescape($src),$ext,$type));
1.492     raeburn  2429:                     }
                   2430:                 }
                   2431:             }
                   2432:             foreach my $idx (keys(%remparam)) {
                   2433:                 if (ref($remparam{$idx}) eq 'ARRAY') {
                   2434:                     foreach my $name (@{$remparam{$idx}}) {   
                   2435:                         &LONCAPA::map::delparameter($idx,'parameter_'.$name);
1.491     raeburn  2436:                     }
                   2437:                 }
                   2438:             }
1.533     raeburn  2439:             if (values(%lockerrors) > 0) {
                   2440:                 $lockmsg = join('<br />',values(%lockerrors));
                   2441:             }
1.491     raeburn  2442:             my $storefn;
                   2443:             if ($key eq $oldurl) {
                   2444:                 $storefn = $url;
                   2445:                 $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
                   2446:             } else {
                   2447:                 $storefn = $key;
                   2448:                 $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{};
1.529     raeburn  2449:                 if ($prefixchg && $before{'map'} && $after{'map'}) {
                   2450:                     $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/;
1.491     raeburn  2451:                 }
1.529     raeburn  2452:                 if ($newsubdir{$key}) {
                   2453:                     $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
1.492     raeburn  2454:                 }
1.491     raeburn  2455:             }
1.492     raeburn  2456:             my $report;
                   2457:             if ($folder !~ /^supplemental/) {
                   2458:                 $report = 1;
                   2459:             }
1.527     raeburn  2460:             (my $outtext,$errtext) =
1.492     raeburn  2461:                 &LONCAPA::map::storemap("/uploaded/$cdom/$cnum/$storefn",1,$report);
                   2462:             if ($errtext) {
1.529     raeburn  2463:                 if ($caller eq 'paste') {
1.533     raeburn  2464:                     return (&mt('Paste failed: an error occurred saving the folder or page.'));
1.529     raeburn  2465:                 }
1.491     raeburn  2466:             }
                   2467:         }
                   2468:     }
1.533     raeburn  2469:     return ('ok',\@msgs,$lockmsg);
1.491     raeburn  2470: }
                   2471: 
                   2472: sub copy_dependencies {
                   2473:     my ($item,$storefn,$relpath,$errors,$contentref) = @_;
                   2474:     my $content;
                   2475:     if (ref($contentref)) {
                   2476:         $content = $$contentref;
                   2477:     } else {
                   2478:         $content = &Apache::lonnet::getfile($item);
                   2479:     }
                   2480:     unless ($content eq '-1') {
                   2481:         my $mm = new File::MMagic;
                   2482:         my $mimetype = $mm->checktype_contents($content);
                   2483:         if ($mimetype eq 'text/html') {
                   2484:             my (%allfiles,%codebase,$state);
                   2485:             my $res = &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,\$content);
                   2486:             if ($res eq 'ok') {
                   2487:                 my ($numexisting,$numpathchanges,$existing);
                   2488:                 (undef,$numexisting,$numpathchanges,$existing) =
                   2489:                     &Apache::loncommon::ask_for_embedded_content(
                   2490:                         '/adm/coursedocs',$state,\%allfiles,\%codebase,
                   2491:                         {'error_on_invalid_names'   => 1,
                   2492:                          'ignore_remote_references' => 1,
                   2493:                          'docs_url'                 => $item,
                   2494:                          'context'                  => 'paste'});
                   2495:                 if ($numexisting > 0) {
                   2496:                     if (ref($existing) eq 'HASH') {
                   2497:                         foreach my $dep (keys(%{$existing})) {
                   2498:                             my $depfile = $dep;
                   2499:                             unless ($depfile =~ m{^\Q$relpath\E}) {
                   2500:                                 $depfile = $relpath.$dep;
                   2501:                             }
                   2502:                             my $depcontent = &Apache::lonnet::getfile($depfile);
                   2503:                             unless ($depcontent eq '-1') {
                   2504:                                 my $storedep = $dep;
                   2505:                                 $storedep =~ s{^\Q$relpath\E}{};
                   2506:                                 my $dep_url =
                   2507:                                     &Apache::lonclonecourse::writefile(
                   2508:                                         $env{'request.course.id'},
                   2509:                                         $storefn.$storedep,$depcontent);
                   2510:                                 if ($dep_url eq '/adm/notfound.html') {
                   2511:                                     if (ref($errors) eq 'HASH') {
                   2512:                                         $errors->{$depfile} = 1;
                   2513:                                     }
                   2514:                                 } else {
                   2515:                                     &copy_dependencies($depfile,$storefn,$relpath,$errors,\$depcontent);
                   2516:                                 }
                   2517:                             }
                   2518:                         }
1.488     raeburn  2519:                     }
                   2520:                 }
                   2521:             }
                   2522:         }
                   2523:     }
                   2524:     return;
                   2525: }
                   2526: 
1.329     droeschl 2527: my %parameter_type = ( 'randompick'     => 'int_pos',
                   2528: 		       'hiddenresource' => 'string_yesno',
                   2529: 		       'encrypturl'     => 'string_yesno',
                   2530: 		       'randomorder'    => 'string_yesno',);
                   2531: my $valid_parameters_re = join('|',keys(%parameter_type));
                   2532: # set parameters
                   2533: sub update_parameter {
1.537     raeburn  2534:     if ($env{'form.changeparms'} eq 'all') {
                   2535:         my (@allidx,@allmapidx,%allchecked,%currchecked);
                   2536:         %allchecked = (
                   2537:                          'hiddenresource' => {},
                   2538:                          'encrypturl'     => {},
                   2539:                          'randompick'     => {},
                   2540:                          'randomorder'    => {},
                   2541:                       );
                   2542:         foreach my $which (keys(%allchecked)) {
                   2543:             $env{'form.all'.$which} =~ s/,$//;   
                   2544:             if ($which eq 'randompick') {
                   2545:                 foreach my $item (split(/,/,$env{'form.all'.$which})) {
                   2546:                     my ($res,$value) = split(/:/,$item);
                   2547:                     if ($value =~ /^\d+$/) {
                   2548:                         $allchecked{$which}{$res} = $value;
                   2549:                     }
                   2550:                 }
                   2551:             } else {
1.539     raeburn  2552:                 if ($env{'form.all'.$which}) {
                   2553:                     map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.all'.$which});
                   2554:                 }
1.537     raeburn  2555:             }
                   2556:         }
                   2557:         my $haschanges = 0;
                   2558:         foreach my $res (@LONCAPA::map::order) {
                   2559:             my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
                   2560:             $name=&LONCAPA::map::qtescape($name);
                   2561:             $url=&LONCAPA::map::qtescape($url);
                   2562:             next unless ($name && $url);
                   2563:             my $is_map;
                   2564:             if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
                   2565:                 $is_map = 1;
                   2566:             }
                   2567:             foreach my $which (keys(%allchecked)) {
                   2568:                 if (($which eq 'randompick' || $which eq 'randomorder')) {
                   2569:                     next if (!$is_map);
                   2570:                 } 
                   2571:                 my $oldvalue = 0;
                   2572:                 my $newvalue = 0;
                   2573:                 if ($allchecked{$which}{$res}) {
                   2574:                     $newvalue = $allchecked{$which}{$res};
                   2575:                 }
                   2576:                 my $current = (&LONCAPA::map::getparameter($res,'parameter_'.$which))[0];
                   2577:                 if ($which eq 'randompick') {
                   2578:                     if ($current =~ /^(\d+)$/) {
                   2579:                         $oldvalue = $1;
                   2580:                     }
                   2581:                 } else {
                   2582:                     if ($current =~ /^yes$/i) {
                   2583:                         $oldvalue = 1;
                   2584:                     }
                   2585:                 }
                   2586:                 if ($oldvalue ne $newvalue) {
                   2587:                     $haschanges = 1;
                   2588:                     if ($newvalue) {
                   2589:                         my $storeval = 'yes';
                   2590:                         if ($which eq 'randompick') {
                   2591:                             $storeval = $newvalue;
                   2592:                         }
                   2593:                         &LONCAPA::map::storeparameter($res,'parameter_'.$which,
                   2594:                                                       $storeval,
                   2595:                                                       $parameter_type{$which});
                   2596:                         &remember_parms($res,$which,'set',$storeval);
                   2597:                     } elsif ($oldvalue) {
                   2598:                         &LONCAPA::map::delparameter($res,'parameter_'.$which);
                   2599:                         &remember_parms($res,$which,'del');
                   2600:                     }
                   2601:                 }
                   2602:             }
                   2603:         }
                   2604:         return $haschanges;
                   2605:     } else {
                   2606:         return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/);
1.329     droeschl 2607: 
1.537     raeburn  2608:         my $which = $env{'form.changeparms'};
                   2609:         my $idx = $env{'form.setparms'};
                   2610:         if ($env{'form.'.$which.'_'.$idx}) {
                   2611: 	    my $value = ($which eq 'randompick') ? $env{'form.rpicknum_'.$idx}
                   2612: 	                                         : 'yes';
                   2613: 	    &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value,
                   2614: 				          $parameter_type{$which});
                   2615: 	    &remember_parms($idx,$which,'set',$value);
                   2616:         } else {
                   2617: 	    &LONCAPA::map::delparameter($idx,'parameter_'.$which);
1.329     droeschl 2618: 
1.537     raeburn  2619: 	    &remember_parms($idx,$which,'del');
                   2620:         }
                   2621:         return 1;
1.329     droeschl 2622:     }
                   2623: }
                   2624: 
                   2625: 
                   2626: sub handle_edit_cmd {
                   2627:     my ($coursenum,$coursedom) =@_;
1.543     raeburn  2628:     if ($env{'form.cmd'} eq '') {
                   2629:         return 0;
                   2630:     }
1.329     droeschl 2631:     my ($cmd,$idx)=split('_',$env{'form.cmd'});
                   2632: 
                   2633:     my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
                   2634:     my ($title, $url, @rrest) = split(':', $ratstr);
                   2635: 
1.538     raeburn  2636:     if ($cmd eq 'remove') {
1.329     droeschl 2637: 	if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
1.463     www      2638: 	    ($url!~/$LONCAPA::assess_page_seq_re/)) {
1.329     droeschl 2639: 	    &Apache::lonnet::removeuploadedurl($url);
                   2640: 	} else {
                   2641: 	    &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
                   2642: 	}
                   2643: 	splice(@LONCAPA::map::order, $idx, 1);
                   2644: 
                   2645:     } elsif ($cmd eq 'cut') {
                   2646: 	&LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
                   2647: 	splice(@LONCAPA::map::order, $idx, 1);
                   2648: 
1.344     bisitz   2649:     } elsif ($cmd eq 'up'
1.329     droeschl 2650: 	     && ($idx) && (defined($LONCAPA::map::order[$idx-1]))) {
                   2651: 	@LONCAPA::map::order[$idx-1,$idx] = @LONCAPA::map::order[$idx,$idx-1];
                   2652: 
                   2653:     } elsif ($cmd eq 'down'
                   2654: 	     && defined($LONCAPA::map::order[$idx+1])) {
                   2655: 	@LONCAPA::map::order[$idx+1,$idx] = @LONCAPA::map::order[$idx,$idx+1];
                   2656: 
                   2657:     } elsif ($cmd eq 'rename') {
                   2658: 	my $comment = &LONCAPA::map::qtunescape($env{'form.title'});
                   2659: 	if ($comment=~/\S/) {
                   2660: 	    $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]=
                   2661: 		$comment.':'.join(':', $url, @rrest);
                   2662: 	}
                   2663: # Devalidate title cache
                   2664: 	my $renamed_url=&LONCAPA::map::qtescape($url);
                   2665: 	&Apache::lonnet::devalidate_title_cache($renamed_url);
1.538     raeburn  2666: 
1.329     droeschl 2667:     } else {
                   2668: 	return 0;
                   2669:     }
                   2670:     return 1;
                   2671: }
                   2672: 
                   2673: sub editor {
1.458     raeburn  2674:     my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype,
1.508     raeburn  2675:         $supplementalflag,$orderhash,$iconpath,$pathitem)=@_;
1.519     raeburn  2676:     my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container);
1.510     raeburn  2677:     if ($allowed) {
1.519     raeburn  2678:         (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
                   2679:          $is_random_order,$container) =
1.510     raeburn  2680:             &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1);
                   2681:         $r->print($breadcrumbtrail);
1.519     raeburn  2682:     } elsif ($env{'form.folderpath'} =~ /\:1$/) {
                   2683:         $container = 'page'; 
                   2684:     } else {
                   2685:         $container = 'sequence';
1.510     raeburn  2686:     }
1.484     raeburn  2687: 
1.525     raeburn  2688:     my $jumpto;
                   2689: 
                   2690:     unless ($supplementalflag) {
1.546     raeburn  2691:         $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container";
1.525     raeburn  2692:     }
1.484     raeburn  2693: 
                   2694:     unless ($allowed) {
                   2695:         $randompick = -1;
                   2696:     }
                   2697: 
1.329     droeschl 2698:     my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                   2699: 				    $folder.'.'.$container);
                   2700:     return $errtext if ($fatal);
                   2701: 
                   2702:     if ($#LONCAPA::map::order<1) {
                   2703: 	my $idx=&LONCAPA::map::getresidx();
                   2704: 	if ($idx<=0) { $idx=1; }
                   2705:        	$LONCAPA::map::order[0]=$idx;
                   2706:         $LONCAPA::map::resources[$idx]='';
                   2707:     }
1.364     bisitz   2708: 
1.329     droeschl 2709: # ------------------------------------------------------------ Process commands
                   2710: 
                   2711: # ---------------- if they are for this folder and user allowed to make changes
                   2712:     if (($allowed) && ($env{'form.folder'} eq $folder)) {
                   2713: # set parameters and change order
                   2714: 	&snapshotbefore();
                   2715: 
                   2716: 	if (&update_parameter()) {
                   2717: 	    ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   2718: 	    return $errtext if ($fatal);
                   2719: 	}
                   2720: 
                   2721: 	if ($env{'form.newpos'} && $env{'form.currentpos'}) {
                   2722: # change order
                   2723: 	    my $res = splice(@LONCAPA::map::order,$env{'form.currentpos'}-1,1);
                   2724: 	    splice(@LONCAPA::map::order,$env{'form.newpos'}-1,0,$res);
                   2725: 
                   2726: 	    ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   2727: 	    return $errtext if ($fatal);
                   2728: 	}
1.364     bisitz   2729: 
1.329     droeschl 2730: 	if ($env{'form.pastemarked'}) {
1.491     raeburn  2731:             my %paste_errors;
1.533     raeburn  2732:             my ($paste_res,$save_error,$pastemsgarray,$lockerror) =
1.492     raeburn  2733:                 &do_paste_from_buffer($coursenum,$coursedom,$folder,$container,
                   2734:                                       \%paste_errors);
1.541     raeburn  2735:             if (ref($pastemsgarray) eq 'ARRAY') {
                   2736:                 if (@{$pastemsgarray} > 0) {
                   2737:                     $r->print('<p class="LC_info">'.
                   2738:                               join('<br />',@{$pastemsgarray}).
1.533     raeburn  2739:                               '</p>');
                   2740:                 }
1.541     raeburn  2741:             }
                   2742:             if ($lockerror) {
                   2743:                 $r->print('<p class="LC_error">'.
                   2744:                           $lockerror.
                   2745:                           '</p>');
                   2746:             }
                   2747:             if ($save_error ne '') {
                   2748:                 return $save_error; 
                   2749:             }
                   2750:             if ($paste_res) {
                   2751:                 my %errortext = &Apache::lonlocal::texthash (
                   2752:                                     fail      => 'Storage of folder contents failed',
                   2753:                                     failread  => 'Reading folder contents failed',
                   2754:                                     failstore => 'Storage of folder contents failed',
                   2755:                                 );
                   2756:                 if ($errortext{$paste_res}) {
                   2757:                     $r->print('<p class="LC_error">'.$errortext{$paste_res}.'</p>');
1.492     raeburn  2758:                 }
1.329     droeschl 2759:             }
1.491     raeburn  2760:             if (keys(%paste_errors) > 0) {
1.538     raeburn  2761:                 $r->print('<p class="LC_warning">'."\n".
1.491     raeburn  2762:                           &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".
                   2763:                           '<ul>'."\n");
                   2764:                 foreach my $key (sort(keys(%paste_errors))) {
                   2765:                     $r->print('<li>'.$key.'</li>'."\n");
                   2766:                 }
                   2767:                 $r->print('</ul></p>'."\n");
                   2768:             }
1.538     raeburn  2769: 	} elsif ($env{'form.clearmarked'}) {
                   2770:             my $output = &do_buffer_empty();
                   2771:             if ($output) {
                   2772:                 $r->print('<p class="LC_info">'.$output.'</p>');
                   2773:             }
                   2774:         }
1.329     droeschl 2775: 
                   2776: 	$r->print($upload_output);
                   2777: 
1.538     raeburn  2778: # Rename, cut, copy or remove a single resource
1.329     droeschl 2779: 	if (&handle_edit_cmd()) {
1.492     raeburn  2780:             my $contentchg;
1.538     raeburn  2781:             if ($env{'form.cmd'} =~ m{^(del|cut)_}) {
1.492     raeburn  2782:                 $contentchg = 1;
                   2783:             }
                   2784: 	    ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container,$contentchg);
1.329     droeschl 2785: 	    return $errtext if ($fatal);
                   2786: 	}
1.538     raeburn  2787: 
                   2788: # Cut, copy and/or remove multiple resources
                   2789:         if ($env{'form.multichange'}) {
                   2790:             my %allchecked = (
                   2791:                                cut     => {},
                   2792:                                remove  => {},
                   2793:                              );
                   2794:             my $needsupdate;
                   2795:             foreach my $which (keys(%allchecked)) {
                   2796:                 $env{'form.multi'.$which} =~ s/,$//;
                   2797:                 if ($env{'form.multi'.$which}) {
                   2798:                     map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.multi'.$which});
                   2799:                     if (ref($allchecked{$which}) eq 'HASH') {
                   2800:                         $needsupdate += scalar(keys(%{$allchecked{$which}}));
                   2801:                     }
                   2802:                 }
                   2803:             }
                   2804:             if ($needsupdate) {
                   2805:                 my $haschanges = 0;
                   2806:                 my %curr_groups = &Apache::longroup::coursegroups();
                   2807:                 my $total = scalar(@LONCAPA::map::order) - 1; 
                   2808:                 for (my $i=$total; $i>=0; $i--) {
                   2809:                     my $res = $LONCAPA::map::order[$i];
                   2810:                     my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
                   2811:                     $name=&LONCAPA::map::qtescape($name);
                   2812:                     $url=&LONCAPA::map::qtescape($url);
                   2813:                     next unless ($name && $url);
                   2814:                     my %denied =
                   2815:                         &action_restrictions($coursenum,$coursedom,$url,
                   2816:                                              $env{'form.folderpath'},\%curr_groups);
                   2817:                     foreach my $which (keys(%allchecked)) {
                   2818:                         next if ($denied{$which});
                   2819:                         next unless ($allchecked{$which}{$res});
                   2820:                         if ($which eq 'remove') {
                   2821:                             if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
                   2822:                                 ($url!~/$LONCAPA::assess_page_seq_re/)) {
                   2823:                                 &Apache::lonnet::removeuploadedurl($url);
                   2824:                             } else {
                   2825:                                 &LONCAPA::map::makezombie($res);
                   2826:                             }
                   2827:                             splice(@LONCAPA::map::order,$i,1);
                   2828:                             $haschanges ++;
                   2829:                         } elsif ($which eq 'cut') {
                   2830:                             &LONCAPA::map::makezombie($res);
                   2831:                             splice(@LONCAPA::map::order,$i,1);
                   2832:                             $haschanges ++;
                   2833:                         }
                   2834:                     }
                   2835:                 }
                   2836:                 if ($haschanges) {
                   2837:                     ($errtext,$fatal) = 
                   2838:                         &storemap($coursenum,$coursedom,$folder.'.'.$container,1);
                   2839:                     return $errtext if ($fatal);
                   2840:                 }
                   2841:             }
                   2842:         }
                   2843: 
1.329     droeschl 2844: # Group import/search
                   2845: 	if ($env{'form.importdetail'}) {
                   2846: 	    my @imports;
                   2847: 	    foreach my $item (split(/\&/,$env{'form.importdetail'})) {
                   2848: 		if (defined($item)) {
                   2849: 		    my ($name,$url,$residx)=
1.533     raeburn  2850: 			map { &unescape($_); } split(/\=/,$item);
                   2851:                     if ($url =~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) {
                   2852:                         my ($suffix,$errortxt,$locknotfreed) =
                   2853:                             &new_timebased_suffix($coursedom,$coursenum,'map',$1,$2);
1.504     raeburn  2854:                         if ($locknotfreed) {
                   2855:                             $r->print($locknotfreed);
                   2856:                         }
                   2857:                         if ($suffix) {
                   2858:                             $url =~ s/_new\./_$suffix./; 
                   2859:                         } else {
                   2860:                             return $errortxt;
                   2861:                         }
1.533     raeburn  2862:                     } elsif ($url =~ m{^/adm/$match_domain/$match_username/new/(smppg|bulletinboard)$}) {
                   2863:                         my $type = $1;
                   2864:                         my ($suffix,$errortxt,$locknotfreed) =
                   2865:                             &new_timebased_suffix($coursedom,$coursenum,$type);
                   2866:                         if ($locknotfreed) {
                   2867:                             $r->print($locknotfreed);
                   2868:                         }
                   2869:                         if ($suffix) {
                   2870:                             $url =~ s{^(/adm/$match_domain/$match_username)/new}{$1/$suffix};
                   2871:                         } else {
                   2872:                             return $errortxt;
                   2873:                         }
1.534     raeburn  2874:                     } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) {
                   2875:                         if ($supplementalflag) {
                   2876:                             next unless ($1 eq 'supplemental');
                   2877:                             if ($folder eq 'supplemental') {
                   2878:                                 next unless ($2 eq 'default');
                   2879:                             } else {
                   2880:                                 next unless ($folder eq 'supplemental_'.$2);
                   2881:                             }
                   2882:                         } else {
                   2883:                             next unless ($1 eq 'docs');
                   2884:                             if ($folder eq 'default') {
                   2885:                                 next unless ($2 eq 'default');
                   2886:                             } else {
                   2887:                                 next unless ($folder eq 'default_'.$2);
                   2888:                             }
                   2889:                         }
1.504     raeburn  2890:                     }
1.329     droeschl 2891: 		    push(@imports, [$name, $url, $residx]);
                   2892: 		}
                   2893: 	    }
1.530     raeburn  2894:             ($errtext,$fatal,my $fixuperrors) =
1.529     raeburn  2895:                 &group_import($coursenum, $coursedom, $folder,$container,
                   2896:                               'londocs',@imports);
1.329     droeschl 2897: 	    return $errtext if ($fatal);
1.529     raeburn  2898:             if ($fixuperrors) {
                   2899:                 $r->print($fixuperrors);
                   2900:             }
1.329     droeschl 2901: 	}
                   2902: # Loading a complete map
                   2903: 	if ($env{'form.loadmap'}) {
                   2904: 	    if ($env{'form.importmap'}=~/\w/) {
                   2905: 		foreach my $res (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
                   2906: 		    my ($title,$url,$ext,$type)=split(/\:/,$res);
                   2907: 		    my $idx=&LONCAPA::map::getresidx($url);
                   2908: 		    $LONCAPA::map::resources[$idx]=$res;
                   2909: 		    $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx;
                   2910: 		}
                   2911: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.492     raeburn  2912: 					    $folder.'.'.$container,1);
1.329     droeschl 2913: 		return $errtext if ($fatal);
                   2914: 	    } else {
                   2915: 		$r->print('<p><span class="LC_error">'.&mt('No map selected.').'</span></p>');
1.364     bisitz   2916: 
1.329     droeschl 2917: 	    }
                   2918: 	}
                   2919: 	&log_differences($plain);
                   2920:     }
                   2921: # ---------------------------------------------------------------- End commands
                   2922: # ---------------------------------------------------------------- Print screen
                   2923:     my $idx=0;
                   2924:     my $shown=0;
                   2925:     if (($ishidden) || ($isencrypted) || ($randompick>=0) || ($is_random_order)) {
1.381     bisitz   2926: 	$r->print('<div class="LC_Box">'.
1.432     raeburn  2927:           '<ol class="LC_docs_parameters"><li class="LC_docs_parameters_title">'.&mt('Parameters:').'</li>'.
                   2928: 		  ($randompick>=0?'<li>'.&mt('randomly pick [quant,_1,resource]',$randompick).'</li>':'').
                   2929: 		  ($ishidden?'<li>'.&mt('contents hidden').'</li>':'').
                   2930: 		  ($isencrypted?'<li>'.&mt('URLs hidden').'</li>':'').
                   2931: 		  ($is_random_order?'<li>'.&mt('random order').'</li>':'').
1.431     raeburn  2932: 		  '</ol>');
1.381     bisitz   2933:         if ($randompick>=0) {
                   2934:             $r->print('<p class="LC_warning">'
                   2935:                  .&mt('Caution: this folder is set to randomly pick a subset'
                   2936:                      .' of resources. Adding or removing resources from this'
                   2937:                      .' folder will change the set of resources that the'
                   2938:                      .' students see, resulting in spurious or missing credit'
                   2939:                      .' for completed problems, not limited to ones you'
                   2940:                      .' modify. Do not modify the contents of this folder if'
                   2941:                      .' it is in active student use.')
                   2942:                  .'</p>'
                   2943:             );
                   2944:         }
                   2945:         if ($is_random_order) {
                   2946:             $r->print('<p class="LC_warning">'
                   2947:                  .&mt('Caution: this folder is set to randomly order its'
                   2948:                      .' contents. Adding or removing resources from this folder'
                   2949:                      .' will change the order of resources shown.')
                   2950:                  .'</p>'
                   2951:             );
                   2952:         }
                   2953:         $r->print('</div>');
1.364     bisitz   2954:     }
1.381     bisitz   2955: 
1.538     raeburn  2956:     my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups);
                   2957:     %filters =  (
1.543     raeburn  2958:                   canremove      => [],
                   2959:                   cancut         => [],
                   2960:                   cancopy        => [],
                   2961:                   hiddenresource => [],
                   2962:                   encrypturl     => [],
                   2963:                   randomorder    => [],
                   2964:                   randompick     => [],
1.538     raeburn  2965:                 );
                   2966:     %curr_groups = &Apache::longroup::coursegroups();
1.424     onken    2967:     &Apache::loncommon::start_data_table_count(); #setup a row counter 
1.381     bisitz   2968:     foreach my $res (@LONCAPA::map::order) {
                   2969:         my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
                   2970:         $name=&LONCAPA::map::qtescape($name);
                   2971:         $url=&LONCAPA::map::qtescape($url);
                   2972:         unless ($name) {  $name=(split(/\//,$url))[-1]; }
                   2973:         unless ($name) { $idx++; next; }
1.537     raeburn  2974:         push(@allidx,$res);
                   2975:         if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
                   2976:             push(@allmapidx,$res);
                   2977:         }
1.381     bisitz   2978:         $output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
1.501     raeburn  2979:                               $coursenum,$coursedom,$crstype,
1.538     raeburn  2980:                               $pathitem,$supplementalflag,$container,
                   2981:                               \%filters,\%curr_groups);
1.381     bisitz   2982:         $idx++;
                   2983:         $shown++;
1.329     droeschl 2984:     }
1.424     onken    2985:     &Apache::loncommon::end_data_table_count();
1.510     raeburn  2986: 
1.538     raeburn  2987:     my $need_save;
1.510     raeburn  2988:     if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) {
1.544     raeburn  2989:         my $toolslink;
                   2990:         if ($allowed || &Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
                   2991:             $toolslink = '<table><tr><td>'
1.520     raeburn  2992:                        .&Apache::loncommon::help_open_menu('Navigation Screen',
                   2993:                                                            'Navigation_Screen',undef,'RAT')
                   2994:                        .'</td><td class="LC_middle">'.&mt('Tools:').'</td>'
                   2995:                        .'<td align="left"><ul id="LC_toolbar">'
1.525     raeburn  2996:                        .'<li><a href="/adm/coursedocs?forcesupplement=1&amp;command=editsupp" '
1.520     raeburn  2997:                        .'id="LC_content_toolbar_edittoplevel" '
                   2998:                        .'class="LC_toolbarItem" '
                   2999:                        .'title="'.&mt('Supplemental Content Editor').'">'
                   3000:                        .'</a></li></ul></td></tr></table><br />';
1.544     raeburn  3001:         }
1.510     raeburn  3002:         if ($shown) {
                   3003:             if ($allowed) {
                   3004:                 $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll')
                   3005:                           .&Apache::loncommon::start_data_table(undef,'contentlist')
                   3006:                           .&Apache::loncommon::start_data_table_header_row()
                   3007:                           .'<th colspan="2">'.&mt('Move').'</th>'
1.538     raeburn  3008:                           .'<th colspan="2">'.&mt('Actions').'</th>'
                   3009:                           .'<th>'.&mt('Document').'</th>';
1.510     raeburn  3010:                 if ($folder !~ /^supplemental/) {
                   3011:                     $to_show .= '<th colspan="4">'.&mt('Settings').'</th>';
                   3012:                 }
1.537     raeburn  3013:                 $to_show .= &Apache::loncommon::end_data_table_header_row();
                   3014:                 if ($folder !~ /^supplemental/) {
1.538     raeburn  3015:                     $lists{'canhide'} = join(',',@allidx);
                   3016:                     $lists{'canrandomlyorder'} = join(',',@allmapidx);
1.543     raeburn  3017:                     my @possfilters = ('canremove','cancut','cancopy','hiddenresource','encrypturl',
                   3018:                                        'randomorder','randompick');
                   3019:                     foreach my $item (@possfilters) {
1.538     raeburn  3020:                         if (ref($filters{$item}) eq 'ARRAY') {
1.543     raeburn  3021:                             if (@{$filters{$item}} > 0) {
                   3022:                                 $lists{$item} = join(',',@{$filters{$item}});
                   3023:                             }
1.538     raeburn  3024:                         }
                   3025:                     }
1.537     raeburn  3026:                     if (@allidx > 0) {
                   3027:                         my $path;
                   3028:                         if ($env{'form.folderpath'}) {
                   3029:                             $path = 
                   3030:                                 &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   3031:                         }
1.538     raeburn  3032:                         if (@allidx > 1) {
                   3033:                             $to_show .= 
                   3034:                                 &Apache::loncommon::continue_data_table_row().
                   3035:                                 '<td colspan="2">&nbsp;</td>'.
                   3036:                                 '<td>'.
                   3037:                                 &multiple_check_form('actions',\%lists).
                   3038:                                 '</td>'.
                   3039:                                 '<td>&nbsp;</td>'.
                   3040:                                 '<td>&nbsp;</td>'.
                   3041:                                 '<td colspan="4">'.
                   3042:                                 &multiple_check_form('settings',\%lists).
                   3043:                                 '</td>'.
                   3044:                                 &Apache::loncommon::end_data_table_row();
                   3045:                              $need_save = 1;
                   3046:                         }
1.537     raeburn  3047:                     }
                   3048:                 }
                   3049:                 $to_show .= $output.' '
1.510     raeburn  3050:                            .&Apache::loncommon::end_data_table()
                   3051:                            .'<br style="line-height:2px;" />'
                   3052:                            .&Apache::loncommon::end_scrollbox();
                   3053:             } else {
1.520     raeburn  3054:                 $to_show .= $toolslink
1.510     raeburn  3055:                            .&Apache::loncommon::start_data_table('LC_tableOfContent')
                   3056:                            .$output.' '
                   3057:                            .&Apache::loncommon::end_data_table();
1.393     raeburn  3058:             }
1.510     raeburn  3059:         } else {
1.520     raeburn  3060:             if (!$allowed) {
                   3061:                 $to_show .= $toolslink;
                   3062:             }
1.510     raeburn  3063:             $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll')
                   3064:                        .'<div class="LC_info" id="contentlist">'
1.550     raeburn  3065:                        .&mt('Currently empty')
1.510     raeburn  3066:                        .'</div>'
                   3067:                        .&Apache::loncommon::end_scrollbox();
1.393     raeburn  3068:         }
                   3069:     } else {
1.510     raeburn  3070:         if ($shown) {
                   3071:             $to_show = '<div>'
                   3072:                       .&Apache::loncommon::start_data_table('LC_tableOfContent')
                   3073:                       .$output
                   3074:                       .&Apache::loncommon::end_data_table()
                   3075:                       .'</div>';
                   3076:         } else {
                   3077:             $to_show = '<div class="LC_info" id="contentlist">'
1.550     raeburn  3078:                       .&mt('Currently empty')
1.510     raeburn  3079:                       .'</div>'
                   3080:         }
1.458     raeburn  3081:     }
                   3082:     my $tid = 1;
                   3083:     if ($supplementalflag) {
                   3084:         $tid = 2;
1.329     droeschl 3085:     }
                   3086:     if ($allowed) {
1.484     raeburn  3087:         my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container";
1.538     raeburn  3088:         $r->print(&generate_edit_table($tid,$orderhash,$to_show,$iconpath,
                   3089:                                        $jumpto,$readfile,$need_save,"$folder.$container"));
1.492     raeburn  3090:         &print_paste_buffer($r,$container,$folder,$coursedom,$coursenum);
1.460     raeburn  3091:     } else {
                   3092:         $r->print($to_show);
1.329     droeschl 3093:     }
                   3094:     return;
                   3095: }
                   3096: 
1.538     raeburn  3097: sub multiple_check_form {
                   3098:     my ($caller,$listsref) = @_;
                   3099:     return unless (ref($listsref) eq 'HASH');
                   3100:     my $output =
                   3101:     '<form action="/adm/coursedocs" method="post" name="togglemult'.$caller.'">'.
                   3102:     '<span class="LC_nobreak" style="font-size:x-small;font-weight:bold;">'.
                   3103:     '<label><input type="radio" name="showmultpick" value="0" onclick="javascript:togglePick('."'$caller','0'".');" checked="checked" />'.&mt('one').'</label>'.('&nbsp;'x2).'<label><input type="radio" name="showmultpick" value="1" onclick="javascript:togglePick('."'$caller','1'".');" />'.&mt('multiple').'</label></span><span id="more'.$caller.'" class="LC_nobreak LC_docs_ext_edit"></span></form>'.
                   3104:     '<div id="multi'.$caller.'" style="display:none;margin:0;padding:0;border:0">'.
                   3105:     '<form action="/adm/coursedocs" method="post" name="cumulative'.$caller.'">'."\n".
                   3106:     '<fieldset id="allfields'.$caller.'" style="display:none"><legend style="font-size:x-small;">'.&mt('check/uncheck all').'</legend>'."\n";
                   3107:     if ($caller eq 'settings') {
                   3108:         $output .= 
                   3109:             '<table><tr>'.
                   3110:             '<td class="LC_docs_entry_parameter">'.
                   3111:             '<span class="LC_nobreak"><label>'.
                   3112:             '<input type="checkbox" name="hiddenresourceall" id="hiddenresourceall" onclick="propagateState(this.form,'."'hiddenresource'".')" />'.&mt('Hidden').
                   3113:             '</label></span></td>'.
                   3114:             '<td class="LC_docs_entry_parameter">'.
                   3115:             '<span class="LC_nobreak"><label><input type="checkbox" name="randompickall" id="randompickall" onclick="updatePick(this.form,'."'all','check'".');propagateState(this.form,'."'randompick'".');propagateState(this.form,'."'rpicknum'".');" />'.&mt('Randomly Pick').'</label><span id="rpicktextall"></span><input type="hidden" name="rpicknumall" id="rpicknumall" value="" />'.
                   3116:             '</span></td>'.
                   3117:             '</tr>'."\n".
                   3118:             '<tr>'.
                   3119:             '<td class="LC_docs_entry_parameter">'.
                   3120:             '<span class="LC_nobreak"><label><input type="checkbox" name="encrypturlall" id="encrypturlall" onclick="propagateState(this.form,'."'encrypturl'".')" />'.&mt('URL hidden').'</label></span></td><td class="LC_docs_entry_parameter"><span class="LC_nobreak"><label><input type="checkbox" name="randomorderall" id="randomorderall" onclick="propagateState(this.form,'."'randomorder'".')" />'.&mt('Random Order').
                   3121:             '</label></span>'.
                   3122:             '</td></tr></table>'."\n";
                   3123:     } else {
                   3124:         $output .=
                   3125:             '<table><tr>'.
                   3126:             '<td class="LC_docs_entry_parameter">'.
                   3127:             '<span class="LC_nobreak LC_docs_remove">'.
                   3128:             '<label><input type="checkbox" name="removeall" id="removeall" onclick="propagateState(this.form,'."'remove'".')" />'.&mt('Remove').
                   3129:             '</label></span></td>'.
                   3130:             '<td class="LC_docs_entry_parameter">'.
                   3131:             '<span class="LC_nobreak LC_docs_cut">'.
                   3132:             '<label><input type="checkbox" name="cut" id="cutall" onclick="propagateState(this.form,'."'cut'".');" />'.&mt('Cut').
                   3133:             '</label></span></td>'."\n".
                   3134:             '<td class="LC_docs_entry_parameter">'.
                   3135:             '<span class="LC_nobreak LC_docs_copy">'.
                   3136:             '<label><input type="checkbox" name="copyall" id="copyall" onclick="propagateState(this.form,'."'copy'".')" />'.&mt('Copy').
                   3137:             '</label></span></td>'.
                   3138:             '</tr></table>'."\n";
                   3139:     }
                   3140:     $output .= 
                   3141:         '</fieldset>'.
                   3142:         '<input type="hidden" name="allidx" value="'.$listsref->{'canhide'}.'" />';
                   3143:     if ($caller eq 'settings') {
                   3144:         $output .= 
1.543     raeburn  3145:         '<input type="hidden" name="allmapidx" value="'.$listsref->{'canrandomlyorder'}.'" />'."\n".
                   3146:         '<input type="hidden" name="currhiddenresource" value="'.$listsref->{'hiddenresource'}.'" />'."\n".
                   3147:         '<input type="hidden" name="currencrypturl" value="'.$listsref->{'encrypturl'}.'" />'."\n".
                   3148:         '<input type="hidden" name="currrandomorder" value="'.$listsref->{'randomorder'}.'" />'."\n".
                   3149:         '<input type="hidden" name="currrandompick" value="'.$listsref->{'randompick'}.'" />'."\n";
1.538     raeburn  3150:     } elsif ($caller eq 'actions') {
                   3151:         $output .=
                   3152:         '<input type="hidden" name="allremoveidx" id="allremoveidx" value="'.$listsref->{'canremove'}.'" />'.
                   3153:         '<input type="hidden" name="allcutidx" id="allcutidx" value="'.$listsref->{'cancut'}.'" />'.
                   3154:         '<input type="hidden" name="allcopyidx" id="allcopyidx" value="'.$listsref->{'cancopy'}.'" />';
                   3155:     }
                   3156:     $output .= 
                   3157:         '</form>'.
                   3158:         '</div>';
                   3159:     return $output;
                   3160: }
                   3161: 
1.329     droeschl 3162: sub process_file_upload {
1.552     raeburn  3163:     my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd,$crstype) = @_;
1.329     droeschl 3164: # upload a file, if present
1.552     raeburn  3165:     my $filesize = length($env{'form.uploaddoc'});
                   3166:     if (!$filesize) {
                   3167:         $$upload_output = '<div class="LC_error">'.
                   3168:                            &mt('Unable to upload [_1]. (size = [_2] bytes)',
                   3169:                           '<span class="LC_filename">'.$env{'form.uploaddoc.filename'}.'</span>',
                   3170:                           $filesize).'<br />'.
                   3171:                           &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'.
                   3172:                           '</div>';
                   3173:         return;
                   3174:     }
                   3175:     my $quotatype = 'unofficial';
                   3176:     if ($crstype eq 'Community') {
                   3177:         $quotatype = 'community';    
1.580     raeburn  3178:     } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.coursecode'}) {
1.552     raeburn  3179:         $quotatype = 'official';
1.573     raeburn  3180:     } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.textbook'}) {
                   3181:         $quotatype = 'textbook';
1.552     raeburn  3182:     }
                   3183:     if (&Apache::loncommon::get_user_quota($coursenum,$coursedom,'course',$quotatype)) {
                   3184:         $filesize = int($filesize/1000); #expressed in kb
                   3185:         $$upload_output = &Apache::loncommon::excess_filesize_warning($coursenum,$coursedom,'course',
1.579     raeburn  3186:                                                                       $env{'form.uploaddoc.filename'},$filesize,
                   3187:                                                                       'upload',$quotatype);
1.552     raeburn  3188:         return if ($$upload_output);
                   3189:     }
1.440     raeburn  3190:     my ($parseaction,$showupload,$nextphase,$mimetype);
                   3191:     if ($env{'form.parserflag'}) {
1.329     droeschl 3192:         $parseaction = 'parse';
                   3193:     }
                   3194:     my $folder=$env{'form.folder'};
                   3195:     if ($folder eq '') {
                   3196:         $folder='default';
                   3197:     }
                   3198:     if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
                   3199:         my $errtext='';
                   3200:         my $fatal=0;
                   3201:         my $container='sequence';
1.519     raeburn  3202:         if ($env{'form.folderpath'} =~ /:1$/) {
1.329     droeschl 3203:             $container='page';
                   3204:         }
                   3205:         ($errtext,$fatal)=
1.534     raeburn  3206:             &mapread($coursenum,$coursedom,$folder.'.'.$container);
1.329     droeschl 3207:         if ($#LONCAPA::map::order<1) {
                   3208:             $LONCAPA::map::order[0]=1;
                   3209:             $LONCAPA::map::resources[1]='';
                   3210:         }
                   3211:         my $destination = 'docs/';
                   3212:         if ($folder =~ /^supplemental/) {
                   3213:             $destination = 'supplemental/';
                   3214:         }
                   3215:         if (($folder eq 'default') || ($folder eq 'supplemental')) {
                   3216:             $destination .= 'default/';
                   3217:         } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
                   3218:             $destination .=  $2.'/';
                   3219:         }
1.534     raeburn  3220:         if ($fatal) {
                   3221:             $$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>';
                   3222:             return;
                   3223:         }
1.440     raeburn  3224: # this is for a course, not a user, so set context to coursedoc.
1.329     droeschl 3225:         my $newidx=&LONCAPA::map::getresidx();
                   3226:         $destination .= $newidx;
1.439     raeburn  3227:         my $url=&Apache::lonnet::userfileupload('uploaddoc','coursedoc',$destination,
1.329     droeschl 3228: 						$parseaction,$allfiles,
1.440     raeburn  3229: 						$codebase,undef,undef,undef,undef,
                   3230:                                                 undef,undef,\$mimetype);
                   3231:         if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E.*/([^/]+)$}) {
                   3232:             my $stored = $1;
                   3233:             $showupload = '<p>'.&mt('Uploaded [_1]','<span class="LC_filename">'.
                   3234:                           $stored.'</span>').'</p>';
                   3235:         } else {
                   3236:             my ($filename) = ($env{'form.uploaddoc.filename'} =~ m{([^/]+)$});
                   3237:             
1.457     raeburn  3238:             $$upload_output = '<div class="LC_error" id="uploadfileresult">'.&mt('Unable to save file [_1].','<span class="LC_filename">'.$filename.'</span>').'</div>';
1.440     raeburn  3239:             return;
                   3240:         }
1.329     droeschl 3241:         my $ext='false';
                   3242:         if ($url=~m{^http://}) { $ext='true'; }
                   3243: 	$url     = &LONCAPA::map::qtunescape($url);
                   3244:         my $comment=$env{'form.comment'};
                   3245: 	$comment = &LONCAPA::map::qtunescape($comment);
                   3246:         if ($folder=~/^supplemental/) {
                   3247:               $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                   3248:                   $env{'user.domain'}.'___&&&___'.$comment;
                   3249:         }
                   3250: 
                   3251:         $LONCAPA::map::resources[$newidx]=
                   3252: 	    $comment.':'.$url.':'.$ext.':normal:res';
                   3253:         $LONCAPA::map::order[$#LONCAPA::map::order+1]= $newidx;
                   3254:         ($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.492     raeburn  3255: 				    $folder.'.'.$container,1);
1.329     droeschl 3256:         if ($fatal) {
1.457     raeburn  3257:             $$upload_output = '<div class="LC_error" id="uploadfileresult">'.$errtext.'</div>';
1.440     raeburn  3258:             return;
1.329     droeschl 3259:         } else {
1.440     raeburn  3260:             if ($parseaction eq 'parse' && $mimetype eq 'text/html') {
                   3261:                 $$upload_output = $showupload;
1.384     raeburn  3262:                 my $total_embedded = scalar(keys(%{$allfiles}));
1.329     droeschl 3263:                 if ($total_embedded > 0) {
1.440     raeburn  3264:                     my $uploadphase = 'upload_embedded';
                   3265:                     my $primaryurl = &HTML::Entities::encode($url,'<>&"');
                   3266: 		    my $state = &embedded_form_elems($uploadphase,$primaryurl,$newidx); 
                   3267:                     my ($embedded,$num) = 
                   3268:                         &Apache::loncommon::ask_for_embedded_content(
                   3269:                             '/adm/coursedocs',$state,$allfiles,$codebase,{'docs_url' => $url});
                   3270:                     if ($embedded) {
                   3271:                         if ($num) {
                   3272:                             $$upload_output .=
                   3273: 			         '<p>'.&mt('This file contains embedded multimedia objects, which need to be uploaded.').'</p>'.$embedded;
                   3274:                             $nextphase = $uploadphase;
                   3275:                         } else {
                   3276:                             $$upload_output .= $embedded;
                   3277:                         }
                   3278:                     } else {
                   3279:                         $$upload_output .= &mt('Embedded item(s) already present, so no additional upload(s) required').'<br />';
                   3280:                     }
1.329     droeschl 3281:                 } else {
1.440     raeburn  3282:                     $$upload_output .= &mt('No embedded items identified').'<br />';
1.329     droeschl 3283:                 }
1.457     raeburn  3284:                 $$upload_output = '<div id="uploadfileresult">'.$$upload_output.'</div>';
1.578     raeburn  3285:             } elsif ((&Apache::loncommon::is_archive_file($mimetype)) &&
                   3286:                      ($env{'form.uploaddoc.filename'} =~ /\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/i)) {
1.476     raeburn  3287:                 $nextphase = 'decompress_uploaded';
                   3288:                 my $position = scalar(@LONCAPA::map::order)-1;
                   3289:                 my $noextract = &return_to_editor();
                   3290:                 my $archiveurl = &HTML::Entities::encode($url,'<>&"');
                   3291:                 my %archiveitems = (
                   3292:                     folderpath => $env{'form.folderpath'},
                   3293:                     cmd        => $nextphase,
                   3294:                     newidx     => $newidx,
                   3295:                     position   => $position,
                   3296:                     phase      => $nextphase,
1.477     raeburn  3297:                     comment    => $comment,
1.480     raeburn  3298:                 );
                   3299:                 my ($destination,$dir_root) = &embedded_destination($coursenum,$coursedom);
                   3300:                 my @current = &get_dir_list($url,$coursenum,$coursedom,$newidx); 
1.476     raeburn  3301:                 $$upload_output = $showupload.
                   3302:                                   &Apache::loncommon::decompress_form($mimetype,
                   3303:                                       $archiveurl,'/adm/coursedocs',$noextract,
1.480     raeburn  3304:                                       \%archiveitems,\@current);
1.329     droeschl 3305:             }
                   3306:         }
                   3307:     }
1.440     raeburn  3308:     return $nextphase;
1.329     droeschl 3309: }
                   3310: 
1.480     raeburn  3311: sub get_dir_list {
                   3312:     my ($url,$coursenum,$coursedom,$newidx) = @_;
                   3313:     my ($destination,$dir_root) = &embedded_destination();
                   3314:     my ($dirlistref,$listerror) =  
                   3315:         &Apache::lonnet::dirlist("$dir_root/$destination/$newidx",$coursedom,$coursenum,1);
                   3316:     my @dir_lines;
                   3317:     my $dirptr=16384;
                   3318:     if (ref($dirlistref) eq 'ARRAY') {
                   3319:         foreach my $dir_line (sort
                   3320:                           {
                   3321:                               my ($afile)=split('&',$a,2);
                   3322:                               my ($bfile)=split('&',$b,2);
                   3323:                               return (lc($afile) cmp lc($bfile));
                   3324:                           } (@{$dirlistref})) {
                   3325:             my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16);
                   3326:             $filename =~ s/\s+$//;
                   3327:             next if ($filename =~ /^\.\.?$/); 
                   3328:             my $isdir = 0;
                   3329:             if ($dirptr&$testdir) {
                   3330:                 $isdir = 1;
                   3331:             }
                   3332:             push(@dir_lines, [$filename,$dom,$isdir,$size,$mtime,$obs]);
                   3333:         }
                   3334:     }
                   3335:     return @dir_lines;
                   3336: }
                   3337: 
1.329     droeschl 3338: sub is_supplemental_title {
                   3339:     my ($title) = @_;
                   3340:     return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
                   3341: }
                   3342: 
                   3343: # --------------------------------------------------------------- An entry line
                   3344: 
                   3345: sub entryline {
1.501     raeburn  3346:     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
1.538     raeburn  3347:         $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups)=@_;
1.581     raeburn  3348:     my ($foldertitle,$renametitle,$oldtitle);
1.329     droeschl 3349:     if (&is_supplemental_title($title)) {
1.488     raeburn  3350: 	($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
1.329     droeschl 3351:     } else {
                   3352: 	$title=&HTML::Entities::encode($title,'"<>&\'');
                   3353: 	$renametitle=$title;
                   3354: 	$foldertitle=$title;
                   3355:     }
                   3356: 
                   3357:     my $orderidx=$LONCAPA::map::order[$index];
1.364     bisitz   3358: 
1.329     droeschl 3359:     $renametitle=~s/\\/\\\\/g;
                   3360:     $renametitle=~s/\&quot\;/\\\"/g;
1.581     raeburn  3361:     $renametitle=~s/ /%20/g;
                   3362:     $oldtitle = $renametitle;
1.576     raeburn  3363:     $renametitle=~s/\&#39;/\\\'/g;
1.379     bisitz   3364:     my $line=&Apache::loncommon::start_data_table_row();
1.538     raeburn  3365:     my ($form_start,$form_end,$form_common,$form_param);
1.329     droeschl 3366: # Edit commands
1.535     raeburn  3367:     my ($esc_path, $path, $symb);
1.329     droeschl 3368:     if ($env{'form.folderpath'}) {
                   3369: 	$esc_path=&escape($env{'form.folderpath'});
                   3370: 	$path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   3371: 	# $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"');
                   3372:     }
1.505     raeburn  3373:     my $isexternal;
1.510     raeburn  3374:     if ($residx) {
1.501     raeburn  3375:         my $currurl = $url;
                   3376:         $currurl =~ s{^http(|s)(&colon;|:)//}{/adm/wrapper/ext/};
1.505     raeburn  3377:         if ($currurl =~ m{^/adm/wrapper/ext/}) {
                   3378:             $isexternal = 1;
                   3379:         }
1.510     raeburn  3380:         if (!$supplementalflag) {
                   3381:             my $path = 'uploaded/'.
                   3382:                        $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
                   3383:                        $env{'course.'.$env{'request.course.id'}.'.num'}.'/';
                   3384:             $symb = &Apache::lonnet::encode_symb($path.$folder.".$container",
                   3385:                                                  $residx,
                   3386:                                                  &Apache::lonnet::declutter($currurl));
                   3387:         }
1.501     raeburn  3388:     }
1.538     raeburn  3389:     my ($renamelink,%lt,$ishash);
                   3390:     if (ref($filtersref) eq 'HASH') {
                   3391:         $ishash = 1;
                   3392:     }
                   3393: 
1.329     droeschl 3394:     if ($allowed) {
1.538     raeburn  3395:         $form_start = '
                   3396:    <form action="/adm/coursedocs" method="post">
                   3397: ';
                   3398:         $form_common=(<<END);
                   3399:    <input type="hidden" name="folderpath" value="$path" />
                   3400:    <input type="hidden" name="symb" value="$symb" />
                   3401: END
                   3402:         $form_param=(<<END);
                   3403:    <input type="hidden" name="setparms" value="$orderidx" />
                   3404:    <input type="hidden" name="changeparms" value="0" />
                   3405: END
                   3406:         $form_end = '</form>';
                   3407: 
1.329     droeschl 3408: 	my $incindex=$index+1;
                   3409: 	my $selectbox='';
1.471     raeburn  3410: 	if (($#LONCAPA::map::order>0) &&
1.329     droeschl 3411: 	    ((split(/\:/,
1.344     bisitz   3412: 	     $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1]
                   3413: 	     ne '') &&
1.329     droeschl 3414: 	    ((split(/\:/,
1.344     bisitz   3415: 	     $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1]
1.329     droeschl 3416: 	     ne '')) {
                   3417: 	    $selectbox=
                   3418: 		'<input type="hidden" name="currentpos" value="'.$incindex.'" />'.
1.373     bisitz   3419: 		'<select name="newpos" onchange="this.form.submit()">';
1.329     droeschl 3420: 	    for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) {
                   3421: 		if ($i==$incindex) {
1.358     bisitz   3422: 		    $selectbox.='<option value="" selected="selected">('.$i.')</option>';
1.329     droeschl 3423: 		} else {
                   3424: 		    $selectbox.='<option value="'.$i.'">'.$i.'</option>';
                   3425: 		}
                   3426: 	    }
                   3427: 	    $selectbox.='</select>';
                   3428: 	}
1.501     raeburn  3429: 	%lt=&Apache::lonlocal::texthash(
1.329     droeschl 3430:                 'up' => 'Move Up',
                   3431: 		'dw' => 'Move Down',
                   3432: 		'rm' => 'Remove',
                   3433:                 'ct' => 'Cut',
                   3434: 		'rn' => 'Rename',
1.501     raeburn  3435: 		'cp' => 'Copy',
                   3436:                 'ex' => 'External Resource',
                   3437:                 'ed' => 'Edit',
                   3438:                 'pr' => 'Preview',
                   3439:                 'sv' => 'Save',
                   3440:                 'ul' => 'URL',
                   3441:                 'ti' => 'Title', 
                   3442:                 );
1.538     raeburn  3443: 	my %denied = &action_restrictions($coursenum,$coursedom,$url,
                   3444:                                           $env{'form.folderpath'},
                   3445:                                           $currgroups);
1.517     raeburn  3446:         my ($copylink,$cutlink,$removelink);
1.329     droeschl 3447: 	my $skip_confirm = 0;
                   3448: 	if ( $folder =~ /^supplemental/
                   3449: 	     || ($url =~ m{( /smppg$
                   3450: 			    |/syllabus$
                   3451: 			    |/aboutme$
                   3452: 			    |/navmaps$
                   3453: 			    |/bulletinboard$
1.505     raeburn  3454: 			    |\.html$)}x)
                   3455:              || $isexternal) {
1.329     droeschl 3456: 	    $skip_confirm = 1;
                   3457: 	}
                   3458: 
1.538     raeburn  3459: 	if ($denied{'copy'}) {
1.543     raeburn  3460:             $copylink=(<<ENDCOPY)
1.507     raeburn  3461: <span style="visibility: hidden;">$lt{'cp'}</span>
                   3462: ENDCOPY
                   3463:         } else {
1.538     raeburn  3464:             my $formname = 'edit_copy_'.$orderidx;
                   3465:             my $js = "javascript:checkForSubmit(document.forms.renameform,'copy','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm,'$container','$folder');";
1.329     droeschl 3466: 	    $copylink=(<<ENDCOPY);
1.538     raeburn  3467: <form name="$formname" method="post" action="/adm/coursedocs">
                   3468: $form_common
1.540     raeburn  3469: <input type="checkbox" name="copy" id="copy_$orderidx" value="$orderidx" onclick="javascript:singleCheck(this,'$orderidx','copy');" class="LC_hidden" /><a href="$js" class="LC_docs_copy">$lt{'cp'}</a>
1.538     raeburn  3470: $form_end
1.329     droeschl 3471: ENDCOPY
1.538     raeburn  3472:             if (($ishash) && (ref($filtersref->{'cancopy'}) eq 'ARRAY')) {
                   3473:                 push(@{$filtersref->{'cancopy'}},$orderidx);
                   3474:             }
1.329     droeschl 3475:         }
1.538     raeburn  3476: 	if ($denied{'cut'}) {
1.507     raeburn  3477:             $cutlink=(<<ENDCUT);
                   3478: <span style="visibility: hidden;">$lt{'ct'}</span>
                   3479: ENDCUT
                   3480:         } else {
1.538     raeburn  3481:             my $formname = 'edit_cut_'.$orderidx;
                   3482:             my $js = "javascript:checkForSubmit(document.forms.renameform,'cut','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm,'$container','$folder');";
1.329     droeschl 3483: 	    $cutlink=(<<ENDCUT);
1.538     raeburn  3484: <form name="$formname" method="post" action="/adm/coursedocs">
                   3485: $form_common
1.542     raeburn  3486: <input type="hidden" name="skip_$orderidx" id="skip_cut_$orderidx" value="$skip_confirm" />
1.540     raeburn  3487: <input type="checkbox" name="cut" id="cut_$orderidx" value="$orderidx" onclick="javascript:singleCheck(this,'$orderidx','cut');" class="LC_hidden" /><a href="$js" class="LC_docs_cut">$lt{'ct'}</a>
1.538     raeburn  3488: $form_end
1.329     droeschl 3489: ENDCUT
1.538     raeburn  3490:             if (($ishash) && (ref($filtersref->{'cancut'}) eq 'ARRAY')) {
                   3491:                 push(@{$filtersref->{'cancut'}},$orderidx);
                   3492:             }
1.329     droeschl 3493:         }
1.538     raeburn  3494:         if ($denied{'remove'}) {
1.507     raeburn  3495:             $removelink=(<<ENDREM);
                   3496: <span style="visibility: hidden;">$lt{'rm'}</a>
                   3497: ENDREM
                   3498:         } else {
1.538     raeburn  3499:             my $formname = 'edit_remove_'.$orderidx;
                   3500:             my $js = "javascript:checkForSubmit(document.forms.renameform,'remove','actions','$orderidx','$esc_path','$index','$renametitle',$skip_confirm);";
1.497     raeburn  3501:             $removelink=(<<ENDREM);
1.538     raeburn  3502: <form name="$formname" method="post" action="/adm/coursedocs">
                   3503: $form_common
1.542     raeburn  3504: <input type="hidden" name="skip_$orderidx" id="skip_remove_$orderidx" value="$skip_confirm" />
1.540     raeburn  3505: <input type="checkbox" name="remove" id="remove_$orderidx" value="$orderidx" onclick="javascript:singleCheck(this,'$orderidx','remove');" class="LC_hidden" /><a href="$js" class="LC_docs_remove">$lt{'rm'}</a>
1.538     raeburn  3506: $form_end
1.497     raeburn  3507: ENDREM
1.538     raeburn  3508:             if (($ishash) && (ref($filtersref->{'canremove'}) eq 'ARRAY')) {
                   3509:                 push(@{$filtersref->{'canremove'}},$orderidx);
                   3510:             }
1.497     raeburn  3511:         }
1.551     raeburn  3512:         $renamelink=(<<ENDREN);
1.581     raeburn  3513: <a href='javascript:changename("$esc_path","$index","$oldtitle");' class="LC_docs_rename">$lt{'rn'}</a>
1.507     raeburn  3514: ENDREN
1.329     droeschl 3515: 	$line.=(<<END);
                   3516: <td>
1.379     bisitz   3517: <div class="LC_docs_entry_move">
1.535     raeburn  3518:   <a href='/adm/coursedocs?cmd=up_$index&amp;folderpath=$esc_path&amp;symb=$symb'>
1.501     raeburn  3519:     <img src="${iconpath}move_up.gif" alt="$lt{'up'}" class="LC_icon" />
1.379     bisitz   3520:   </a>
                   3521: </div>
                   3522: <div class="LC_docs_entry_move">
1.536     raeburn  3523:   <a href='/adm/coursedocs?cmd=down_$index&amp;folderpath=$esc_path&amp;symb=$symb'>
1.501     raeburn  3524:     <img src="${iconpath}move_down.gif" alt="$lt{'dw'}" class="LC_icon" />
1.379     bisitz   3525:   </a>
                   3526: </div>
1.329     droeschl 3527: </td>
                   3528: <td>
                   3529:    $form_start
1.538     raeburn  3530:    $form_param
1.478     raeburn  3531:    $form_common
1.329     droeschl 3532:    $selectbox
                   3533:    $form_end
                   3534: </td>
1.540     raeburn  3535: <td class="LC_docs_entry_commands LC_nobreak">
1.497     raeburn  3536: $removelink
1.329     droeschl 3537: $cutlink
                   3538: $copylink
                   3539: </td>
                   3540: END
                   3541:     }
                   3542: # Figure out what kind of a resource this is
                   3543:     my ($extension)=($url=~/\.(\w+)$/);
                   3544:     my $uploaded=($url=~/^\/*uploaded\//);
                   3545:     my $icon=&Apache::loncommon::icon($url);
1.519     raeburn  3546:     my $isfolder;
                   3547:     my $ispage;
                   3548:     my $containerarg;
1.329     droeschl 3549:     if ($uploaded) {
1.472     raeburn  3550:         if (($extension eq 'sequence') || ($extension eq 'page')) {
                   3551:             $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;
1.519     raeburn  3552:             $containerarg = $1;
1.472     raeburn  3553: 	    if ($extension eq 'sequence') {
                   3554: 	        $icon=$iconpath.'navmap.folder.closed.gif';
                   3555:                 $isfolder=1;
                   3556:             } else {
                   3557:                 $icon=$iconpath.'page.gif';
                   3558:                 $ispage=1;
                   3559:             }
                   3560:             if ($allowed) {
                   3561:                 $url='/adm/coursedocs?';
                   3562:             } else {
                   3563:                 $url='/adm/supplemental?';
                   3564:             }
1.329     droeschl 3565: 	} else {
                   3566: 	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
                   3567: 	}
                   3568:     }
1.364     bisitz   3569: 
1.518     raeburn  3570:     my ($editlink,$extresform);
1.329     droeschl 3571:     my $orig_url = $url;
1.340     raeburn  3572:     $orig_url=~s{http(&colon;|:)//https(&colon;|:)//}{https$2//};
1.510     raeburn  3573:     $url=~s{^http(|s)(&colon;|:)//}{/adm/wrapper/ext/};
1.501     raeburn  3574:     if (!$supplementalflag && $residx && $symb) {
                   3575:         if ((!$isfolder) && (!$ispage)) {
                   3576: 	    (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
                   3577: 	    $url=&Apache::lonnet::clutter($url);
                   3578: 	    if ($url=~/^\/*uploaded\//) {
                   3579: 	        $url=~/\.(\w+)$/;
                   3580: 	        my $embstyle=&Apache::loncommon::fileembstyle($1);
                   3581: 	        if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                   3582: 		    $url='/adm/wrapper'.$url;
                   3583: 	        } elsif ($embstyle eq 'ssi') {
                   3584: 		    #do nothing with these
                   3585: 	        } elsif ($url!~/\.(sequence|page)$/) {
                   3586: 		    $url='/adm/coursedocs/showdoc'.$url;
                   3587: 	        }
                   3588: 	    } elsif ($url=~m|^/ext/|) {
                   3589: 	        $url='/adm/wrapper'.$url;
1.329     droeschl 3590: 	    }
1.501     raeburn  3591:             if (&Apache::lonnet::symbverify($symb,$url)) {
                   3592: 	        $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
                   3593:             } else {
                   3594:                 $url='';
                   3595:             }
1.329     droeschl 3596: 	}
                   3597:     }
1.478     raeburn  3598:     my ($rand_pick_text,$rand_order_text);
1.519     raeburn  3599:     if ($isfolder || $ispage || $extension eq 'sequence' || $extension eq 'page') {
1.329     droeschl 3600: 	my $foldername=&escape($foldertitle);
                   3601: 	my $folderpath=$env{'form.folderpath'};
                   3602: 	if ($folderpath) { $folderpath.='&' };
1.510     raeburn  3603:         if (!$allowed && $supplementalflag) {
1.519     raeburn  3604:             $folderpath.=$containerarg.'&'.$foldername;
1.510     raeburn  3605:             $url.='folderpath='.&escape($folderpath);
                   3606:         } else {
1.344     bisitz   3607: # Append randompick number, hidden, and encrypted with ":" to foldername,
1.329     droeschl 3608: # so it gets transferred between levels
1.519     raeburn  3609: 	    $folderpath.=$containerarg.'&'.$foldername.
1.510     raeburn  3610:                                               ':'.(&LONCAPA::map::getparameter($orderidx,
1.329     droeschl 3611:                                               'parameter_randompick'))[0]
                   3612:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
                   3613:                                               'parameter_hiddenresource'))[0]=~/^yes$/i)
                   3614:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
                   3615:                                               'parameter_encrypturl'))[0]=~/^yes$/i)
                   3616:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
1.519     raeburn  3617:                                               'parameter_randomorder'))[0]=~/^yes$/i)
                   3618:                                                .':'.$ispage;
1.510     raeburn  3619: 	    $url.='folderpath='.&escape($folderpath);
                   3620:             my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
                   3621:                                                         'parameter_randompick'))[0];
                   3622:             my $rpckchk;
                   3623:             if ($rpicknum) {
                   3624:                 $rpckchk = ' checked="checked"';
1.543     raeburn  3625:                 if (($ishash) && (ref($filtersref->{'randompick'}) eq 'ARRAY')) {
                   3626:                     push(@{$filtersref->{'randompick'}},$orderidx.':'.$rpicknum);
                   3627:                 }
1.510     raeburn  3628:             }
1.537     raeburn  3629:             my $formname = 'edit_randompick_'.$orderidx;
1.510     raeburn  3630: 	    $rand_pick_text = 
1.478     raeburn  3631: '<form action="/adm/coursedocs" method="post" name="'.$formname.'">'."\n".
1.538     raeburn  3632: $form_param."\n".
1.478     raeburn  3633: $form_common."\n".
1.537     raeburn  3634: '<span class="LC_nobreak"><label><input type="checkbox" name="randompick_'.$orderidx.'" id="randompick_'.$orderidx.'" onclick="'."updatePick(this.form,'$orderidx','check');".'"'.$rpckchk.' /> '.&mt('Randomly Pick').'</label><input type="hidden" name="rpicknum_'.$orderidx.'" id="rpicknum_'.$orderidx.'" value="'.$rpicknum.'" /><span id="randompicknum_'.$orderidx.'">';
1.510     raeburn  3635:             if ($rpicknum ne '') {
                   3636:                 $rand_pick_text .= ':&nbsp;<a href="javascript:updatePick('."document.$formname,'$orderidx','link'".')">'.$rpicknum.'</a>';
                   3637:             }
1.537     raeburn  3638:             $rand_pick_text .= '</span></span>'.
                   3639:                                $form_end;
1.543     raeburn  3640:             my $ro_set;
                   3641:             if ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i) {
                   3642:                 $ro_set = 'checked="checked"';
                   3643:                 if (($ishash) && (ref($filtersref->{'randomorder'}) eq 'ARRAY')) {
                   3644:                     push(@{$filtersref->{'randomorder'}},$orderidx);
                   3645:                 }
                   3646:             }
1.564     raeburn  3647:             $formname = 'edit_rorder_'.$orderidx;
1.510     raeburn  3648: 	    $rand_order_text = 
1.537     raeburn  3649: '<form action="/adm/coursedocs" method="post" name="'.$formname.'">'."\n".
1.538     raeburn  3650: $form_param."\n".
1.537     raeburn  3651: $form_common."\n".
1.538     raeburn  3652: '<span class="LC_nobreak"><label><input type="checkbox" name="randomorder_'.$orderidx.'" id="randomorder_'.$orderidx.'" onclick="checkForSubmit(this.form,'."'randomorder','settings'".');" '.$ro_set.' /> '.&mt('Random Order').' </label></span>'.
1.537     raeburn  3653: $form_end; 
1.510     raeburn  3654:         }
1.509     raeburn  3655:     } elsif ($supplementalflag && !$allowed) {
1.510     raeburn  3656:         $url .= ($url =~ /\?/) ? '&amp;':'?';
1.509     raeburn  3657:         $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');
1.510     raeburn  3658:         if ($title) {
                   3659:             $url .= '&amp;title='.&HTML::Entities::encode($renametitle,'<>&"');
                   3660:         }
1.511     raeburn  3661:         if ($isexternal && $orderidx) {
1.510     raeburn  3662:             $url .= '&amp;idx='.$orderidx;
                   3663:         }
1.329     droeschl 3664:     }
1.519     raeburn  3665:     my ($tdalign,$tdwidth);
1.501     raeburn  3666:     if ($allowed) {
                   3667:         my $fileloc = 
                   3668:             &Apache::lonnet::declutter(&Apache::lonnet::filelocation('',$orig_url));
1.510     raeburn  3669:         if ($isexternal) {
1.518     raeburn  3670:             ($editlink,$extresform) = 
1.510     raeburn  3671:                 &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem);
1.511     raeburn  3672:         } elsif (!$isfolder && !$ispage) {
1.503     raeburn  3673:             my ($cfile,$home,$switchserver,$forceedit,$forceview) = 
                   3674:                 &Apache::lonnet::can_edit_resource($fileloc,$coursenum,$coursedom,$orig_url);
1.511     raeburn  3675:             if (($cfile ne '') && ($symb ne '' || $supplementalflag)) {
1.501     raeburn  3676:                 my $jscall = 
                   3677:                     &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,
                   3678:                                                             $switchserver,
1.503     raeburn  3679:                                                             $forceedit,
1.511     raeburn  3680:                                                             undef,$symb,
                   3681:                                                             &escape($env{'form.folderpath'}),
1.524     raeburn  3682:                                                             $renametitle,'','',1);
1.501     raeburn  3683:                 if ($jscall) {
1.518     raeburn  3684:                     $editlink = '<a class="LC_docs_ext_edit" href="javascript:'.
                   3685:                                 $jscall.'" >'.&mt('Edit').'</a>&nbsp;'."\n";
1.501     raeburn  3686:                 }
                   3687:             }
                   3688:         }
1.519     raeburn  3689:         $tdalign = ' align="right" valign="top"';
                   3690:         $tdwidth = ' width="80%"';
1.329     droeschl 3691:     }
1.408     raeburn  3692:     my $reinit;
                   3693:     if ($crstype eq 'Community') {
                   3694:         $reinit = &mt('(re-initialize community to access)');
                   3695:     } else {
                   3696:         $reinit = &mt('(re-initialize course to access)');
1.519     raeburn  3697:     }
                   3698:     $line.='<td class="LC_docs_entry_commands"'.$tdalign.'><span class="LC_nobreak">'.$editlink.$renamelink;
1.472     raeburn  3699:     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
1.469     www      3700:        $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>';
                   3701:     } elsif ($url) {
1.484     raeburn  3702:        $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&amp;':'?').'inhibitmenu=yes',
1.470     raeburn  3703:                                              '<img src="'.$icon.'" alt="" class="LC_icon" />',600,500);
1.469     www      3704:     } else {
                   3705:        $line.='<img src="'.$icon.'" alt="" class="LC_icon" />';
                   3706:     }
1.519     raeburn  3707:     $line.='</span></td><td'.$tdwidth.'>';
1.472     raeburn  3708:     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
1.469     www      3709:        $line.='<a href="'.$url.'">'.$title.'</a>';
                   3710:     } elsif ($url) {
1.484     raeburn  3711:        $line.=&Apache::loncommon::modal_link($url.(($url=~/\?/)?'&amp;':'?').'inhibitmenu=yes',
1.470     raeburn  3712:                                              $title,600,500);
1.469     www      3713:     } else {
                   3714:        $line.=$title.' <span class="LC_docs_reinit_warn">'.$reinit.'</span>';
                   3715:     }
1.518     raeburn  3716:     $line.="$extresform</td>";
1.478     raeburn  3717:     $rand_pick_text = '&nbsp;' if ($rand_pick_text eq '');
                   3718:     $rand_order_text = '&nbsp;' if ($rand_order_text eq '');
1.329     droeschl 3719:     if (($allowed) && ($folder!~/^supplemental/)) {
                   3720:  	my %lt=&Apache::lonlocal::texthash(
                   3721:  			      'hd' => 'Hidden',
                   3722:  			      'ec' => 'URL hidden');
1.543     raeburn  3723:         my ($enctext,$hidtext);
                   3724:         if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) {
                   3725:             $enctext = ' checked="checked"';
                   3726:             if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) {
                   3727:                 push(@{$filtersref->{'encrypturl'}},$orderidx);
                   3728:             }
                   3729:         }
                   3730:         if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
                   3731:             $hidtext = ' checked="checked"';
                   3732:             if (($ishash) && (ref($filtersref->{'randomorder'}) eq 'ARRAY')) {
                   3733:                 push(@{$filtersref->{'hiddenresource'}},$orderidx);
                   3734:             }
                   3735:         }
1.537     raeburn  3736:         my $formhidden = 'edit_hiddenresource_'.$orderidx;
                   3737:         my $formurlhidden = 'edit_encrypturl_'.$orderidx;
1.329     droeschl 3738: 	$line.=(<<ENDPARMS);
                   3739:   <td class="LC_docs_entry_parameter">
1.537     raeburn  3740:     <form action="/adm/coursedocs" method="post" name="$formhidden">
1.538     raeburn  3741:     $form_param
1.478     raeburn  3742:     $form_common
1.538     raeburn  3743:     <label><input type="checkbox" name="hiddenresource_$orderidx" id="hiddenresource_$orderidx" onclick="checkForSubmit(this.form,'hiddenresource','settings');" $hidtext /> $lt{'hd'}</label>
1.329     droeschl 3744:     $form_end
1.458     raeburn  3745:     <br />
1.537     raeburn  3746:     <form action="/adm/coursedocs" method="post" name="$formurlhidden">
1.538     raeburn  3747:     $form_param
1.478     raeburn  3748:     $form_common
1.538     raeburn  3749:     <label><input type="checkbox" name="encrypturl_$orderidx" id="encrypturl_$orderidx" onclick="checkForSubmit(this.form,'encrypturl','settings');" $enctext /> $lt{'ec'}</label>
1.329     droeschl 3750:     $form_end
                   3751:   </td>
1.478     raeburn  3752:   <td class="LC_docs_entry_parameter">$rand_pick_text<br />
                   3753:                                       $rand_order_text</td>
1.329     droeschl 3754: ENDPARMS
                   3755:     }
1.379     bisitz   3756:     $line.=&Apache::loncommon::end_data_table_row();
1.329     droeschl 3757:     return $line;
                   3758: }
                   3759: 
1.538     raeburn  3760: sub action_restrictions {
                   3761:     my ($cnum,$cdom,$url,$folderpath,$currgroups) = @_;
                   3762:     my %denied = (
                   3763:                    cut    => 0,
                   3764:                    copy   => 0,
                   3765:                    remove => 0,
                   3766:                  );
                   3767:     if ($url=~ m{^/res/.+\.(page|sequence)$}) {
                   3768:         # no copy for published maps
                   3769:         $denied{'copy'} = 1;
                   3770:     } elsif ($url=~m{^/res/lib/templates/}) {
                   3771:        $denied{'copy'} = 1;
                   3772:        $denied{'cut'} = 1;
                   3773:     } elsif ($url eq "/uploaded/$cdom/$cnum/group_allfolders.sequence") {
                   3774:         if ($folderpath =~ /^default&[^\&]+$/) {
                   3775:             if ((ref($currgroups) eq 'HASH') && (keys(%{$currgroups}) > 0)) {
                   3776:                 $denied{'remove'} = 1;
                   3777:             }
                   3778:             $denied{'cut'} = 1;
                   3779:             $denied{'copy'} = 1;
                   3780:         }
                   3781:     } elsif ($url =~ m{^\Q/uploaded/$cdom/$cnum/group_folder_\E(\w+)\.sequence$}) {
                   3782:         my $group = $1;
                   3783:         if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+$/) {
                   3784:             if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
                   3785:                 $denied{'remove'} = 1;
                   3786:             }
                   3787:         }
                   3788:         $denied{'cut'} = 1;
                   3789:         $denied{'copy'} = 1;
                   3790:     } elsif ($url =~ m{^\Q/adm/$cdom/$cnum/\E(\w+)/smppg$}) {
                   3791:         my $group = $1;
                   3792:         if ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&\Qgroup_folder_$group\E\&[^\&]+$/) {
                   3793:             if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
                   3794:                 my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group});
                   3795:                 if (keys(%groupsettings) > 0) {
                   3796:                     $denied{'remove'} = 1;
                   3797:                 }
                   3798:                 $denied{'cut'} = 1;
                   3799:                 $denied{'copy'} = 1;
                   3800:             }
                   3801:         }
                   3802:     } elsif ($folderpath =~ /^default&[^\&]+\&group_allfolders\&[^\&]+\&group_folder_(\w+)\&/) {
                   3803:         my $group = $1;
                   3804:         if ($url =~ /group_boards_\Q$group\E/) {
                   3805:             if ((ref($currgroups) eq 'HASH') && (exists($currgroups->{$group}))) {
                   3806:                 my %groupsettings = &Apache::longroup::get_group_settings($currgroups->{$group});
                   3807:                 if (keys(%groupsettings) > 0) {
                   3808:                     if (ref($groupsettings{'functions'}) eq 'HASH') {
                   3809:                         if ($groupsettings{'functions'}{'discussion'} eq 'on') {
                   3810:                             $denied{'remove'} = 1;
                   3811:                         }
                   3812:                     }
                   3813:                 }
                   3814:                 $denied{'cut'} = 1;
                   3815:                 $denied{'copy'} = 1;
                   3816:             }
                   3817:         }
                   3818:     }
                   3819:     return %denied;
                   3820: }
                   3821: 
1.533     raeburn  3822: sub new_timebased_suffix {
1.538     raeburn  3823:     my ($dom,$num,$type,$area,$container) = @_;
1.533     raeburn  3824:     my ($prefix,$namespace,$idtype,$errtext,$locknotfreed);
1.538     raeburn  3825:     if ($type eq 'paste') {
                   3826:         $prefix = $type;
                   3827:         $namespace = 'courseeditor';
                   3828:     } elsif ($type eq 'map') {
1.533     raeburn  3829:         $prefix = 'docs';
                   3830:         if ($area eq 'supplemental') {
                   3831:             $prefix = 'supp';
                   3832:         }
                   3833:         $prefix .= $container;
                   3834:         $namespace = 'uploadedmaps';
                   3835:     } else {
                   3836:         $prefix = $type;
                   3837:         $namespace = 'templated';
1.504     raeburn  3838:     }
                   3839:     $idtype = 'concat';
                   3840:     my ($suffix,$freedlock,$error) =
1.538     raeburn  3841:         &Apache::lonnet::get_timebased_id($prefix,'num',$namespace,$dom,$num);
1.504     raeburn  3842:     if (!$suffix) {
1.538     raeburn  3843:         if ($type eq 'paste') {
                   3844:             $errtext = &mt('Failed to acquire a unique timestamp-based suffix when adding to the paste buffer.');
                   3845:         } elsif ($type eq 'map') {
1.533     raeburn  3846:             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.');
                   3847:         } elsif ($type eq 'smppg') {
                   3848:             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.');
                   3849:         } else {
1.565     bisitz   3850:             $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new discussion board.');
1.533     raeburn  3851:         }
1.504     raeburn  3852:         if ($error) {
                   3853:             $errtext .= '<br />'.$error;
                   3854:         }
                   3855:     }
                   3856:     if ($freedlock ne 'ok') {
1.533     raeburn  3857:         $locknotfreed = 
                   3858:             '<div class="LC_error">'.
                   3859:             &mt('There was a problem removing a lockfile.').' ';
1.538     raeburn  3860:         if ($type eq 'paste') {
                   3861:             &mt('This will prevent use of the paste buffer until th next log-in.');
                   3862:         } elsif ($type eq 'map') {
1.533     raeburn  3863:             &mt('This will prevent creation of additional folders or composite pages in this course.');
                   3864:         } elsif ($type eq 'smppg') {
                   3865:             $locknotfreed .=
                   3866:                 &mt('This will prevent creation of additional simple pages in this course.');
                   3867:         } else {
                   3868:             $locknotfreed .=
1.565     bisitz   3869:                 &mt('This will prevent creation of additional discussion boards in this course.');
1.533     raeburn  3870:         }
1.538     raeburn  3871:         unless ($type eq 'paste') {
                   3872:             $locknotfreed .=
1.560     raeburn  3873:                 ' '.&mt('Please contact the [_1]helpdesk[_2] for assistance.',
                   3874:                         '<a href="/adm/helpdesk" target="_helpdesk">','</a>');
1.538     raeburn  3875:         }
                   3876:         $locknotfreed .= '</div>';
1.504     raeburn  3877:     }
                   3878:     return ($suffix,$errtext,$locknotfreed);
                   3879: }
                   3880: 
1.329     droeschl 3881: =pod
                   3882: 
                   3883: =item tiehash()
                   3884: 
                   3885: tie the hash
                   3886: 
                   3887: =cut
                   3888: 
                   3889: sub tiehash {
                   3890:     my ($mode)=@_;
                   3891:     $hashtied=0;
                   3892:     if ($env{'request.course.fn'}) {
                   3893: 	if ($mode eq 'write') {
                   3894: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
                   3895: 		    &GDBM_WRCREAT(),0640)) {
                   3896:                 $hashtied=2;
                   3897: 	    }
                   3898: 	} else {
                   3899: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
                   3900: 		    &GDBM_READER(),0640)) {
                   3901:                 $hashtied=1;
                   3902: 	    }
                   3903: 	}
1.364     bisitz   3904:     }
1.329     droeschl 3905: }
                   3906: 
                   3907: sub untiehash {
                   3908:     if ($hashtied) { untie %hash; }
                   3909:     $hashtied=0;
                   3910:     return OK;
                   3911: }
                   3912: 
                   3913: 
                   3914: 
                   3915: 
                   3916: sub checkonthis {
                   3917:     my ($r,$url,$level,$title)=@_;
                   3918:     $url=&unescape($url);
                   3919:     $alreadyseen{$url}=1;
                   3920:     $r->rflush();
                   3921:     if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
                   3922:        $r->print("\n<br />");
                   3923:        if ($level==0) {
                   3924:            $r->print("<br />");
                   3925:        }
                   3926:        for (my $i=0;$i<=$level*5;$i++) {
                   3927:            $r->print('&nbsp;');
                   3928:        }
                   3929:        $r->print('<a href="'.$url.'" target="cat">'.
                   3930: 		 ($title?$title:$url).'</a> ');
                   3931:        if ($url=~/^\/res\//) {
                   3932: 	  my $result=&Apache::lonnet::repcopy(
                   3933:                               &Apache::lonnet::filelocation('',$url));
                   3934:           if ($result eq 'ok') {
                   3935:              $r->print('<span class="LC_success">'.&mt('ok').'</span>');
                   3936:              $r->rflush();
                   3937:              &Apache::lonnet::countacc($url);
                   3938:              $url=~/\.(\w+)$/;
                   3939:              if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
                   3940: 		 $r->print('<br />');
                   3941:                  $r->rflush();
                   3942:                  for (my $i=0;$i<=$level*5;$i++) {
                   3943:                      $r->print('&nbsp;');
                   3944:                  }
                   3945:                  $r->print('- '.&mt('Rendering:').' ');
                   3946: 		 my ($errorcount,$warningcount)=split(/:/,
                   3947: 	       &Apache::lonnet::ssi_body($url,
                   3948: 			       ('grade_target'=>'web',
                   3949: 				'return_only_error_and_warning_counts' => 1)));
                   3950:                  if (($errorcount) ||
                   3951:                      ($warningcount)) {
                   3952: 		     if ($errorcount) {
1.369     bisitz   3953:                         $r->print('<img src="/adm/lonMisc/bomb.gif" alt="'.&mt('bomb').'" /><span class="LC_error">'.
1.329     droeschl 3954:                           &mt('[quant,_1,error]',$errorcount).'</span>');
                   3955:                      }
                   3956: 		     if ($warningcount) {
                   3957:                         $r->print('<span class="LC_warning">'.
                   3958:                           &mt('[quant,_1,warning]',$warningcount).'</span>');
                   3959:                      }
                   3960:                  } else {
                   3961:                      $r->print('<span class="LC_success">'.&mt('ok').'</span>');
                   3962:                  }
                   3963:                  $r->rflush();
                   3964:              }
                   3965: 	     my $dependencies=
                   3966:                 &Apache::lonnet::metadata($url,'dependencies');
                   3967:              foreach my $dep (split(/\,/,$dependencies)) {
                   3968: 		 if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) {
                   3969:                     &checkonthis($r,$dep,$level+1);
                   3970:                  }
                   3971:              }
                   3972:           } elsif ($result eq 'unavailable') {
                   3973:              $r->print('<span class="LC_error">'.&mt('connection down').'</span>');
                   3974:           } elsif ($result eq 'not_found') {
                   3975: 	      unless ($url=~/\$/) {
1.521     bisitz   3976: 		  $r->print('<span class="LC_error">'.&mt('not found').'</span>');
1.329     droeschl 3977: 	      } else {
1.366     bisitz   3978: 		  $r->print('<span class="LC_error">'.&mt('unable to verify variable URL').'</span>');
1.329     droeschl 3979: 	      }
                   3980:           } else {
                   3981:              $r->print('<span class="LC_error">'.&mt('access denied').'</span>');
                   3982:           }
                   3983:        }
                   3984:     }
                   3985: }
                   3986: 
                   3987: 
                   3988: 
                   3989: =pod
                   3990: 
                   3991: =item list_symbs()
                   3992: 
1.485     raeburn  3993: List Content Identifiers
1.329     droeschl 3994: 
                   3995: =cut
                   3996: 
                   3997: sub list_symbs {
                   3998:     my ($r) = @_;
                   3999: 
1.408     raeburn  4000:     my $crstype = &Apache::loncommon::course_type();
1.484     raeburn  4001:     $r->print(&Apache::loncommon::start_page('List of Content Identifiers'));
                   4002:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Identifiers'));
                   4003:     $r->print(&startContentScreen('tools'));
1.329     droeschl 4004:     my $navmap = Apache::lonnavmaps::navmap->new();
                   4005:     if (!defined($navmap)) {
                   4006:         $r->print('<h2>'.&mt('Retrieval of List Failed').'</h2>'.
                   4007:                   '<div class="LC_error">'.
                   4008:                   &mt('Unable to retrieve information about course contents').
                   4009:                   '</div>');
1.408     raeburn  4010:         &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
1.329     droeschl 4011:     } else {
1.484     raeburn  4012:         $r->print('<h4 class="LC_info">'.&mt("$crstype Content Identifiers").'</h4>'.
                   4013:                   &Apache::loncommon::start_data_table().
                   4014:                   &Apache::loncommon::start_data_table_header_row().
                   4015:                   '<th>'.&mt('Title').'</th><th>'.&mt('Identifier').'</th>'.
                   4016:                   &Apache::loncommon::end_data_table_header_row()."\n");
                   4017:         my $count;
1.329     droeschl 4018:         foreach my $res ($navmap->retrieveResources()) {
1.484     raeburn  4019:             $r->print(&Apache::loncommon::start_data_table_row().
                   4020:                       '<td>'.$res->compTitle().'</td>'.
                   4021:                       '<td>'.$res->symb().'</td>'.
1.521     bisitz   4022:                       &Apache::loncommon::end_data_table_row());
1.484     raeburn  4023:             $count ++;
                   4024:         }
                   4025:         if (!$count) {
                   4026:             $r->print(&Apache::loncommon::start_data_table_row().
                   4027:                       '<td colspan="2">'.&mt("$crstype is empty").'</td>'.
                   4028:                       &Apache::loncommon::end_data_table_row()); 
1.329     droeschl 4029:         }
1.484     raeburn  4030:         $r->print(&Apache::loncommon::end_data_table());
1.329     droeschl 4031:     }
1.521     bisitz   4032:     $r->print(&endContentScreen());
1.329     droeschl 4033: }
                   4034: 
                   4035: 
                   4036: sub verifycontent {
                   4037:     my ($r) = @_;
1.408     raeburn  4038:     my $crstype = &Apache::loncommon::course_type();
1.549     raeburn  4039:     $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content'));
                   4040:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content'));
1.484     raeburn  4041:     $r->print(&startContentScreen('tools'));
                   4042:     $r->print('<h4 class="LC_info">'.&mt($crstype.' content verification').'</h4>'); 
1.329     droeschl 4043:    $hashtied=0;
                   4044:    undef %alreadyseen;
                   4045:    %alreadyseen=();
                   4046:    &tiehash();
1.484     raeburn  4047:    
1.329     droeschl 4048:    foreach my $key (keys(%hash)) {
                   4049:        if ($hash{$key}=~/\.(page|sequence)$/) {
                   4050: 	   if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) {
                   4051: 	       $r->print('<hr /><span class="LC_error">'.
1.419     bisitz   4052: 			 &mt('The following sequence or page is included more than once in your '.$crstype.':').' '.
1.329     droeschl 4053: 			 &unescape($hash{$key}).'</span><br />'.
1.419     bisitz   4054: 			 &mt('Note that grading records for problems included in this sequence or folder will overlap.').'<hr />');
1.329     droeschl 4055: 	   }
                   4056:        }
                   4057:        if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) {
                   4058:            &checkonthis($r,$hash{$key},0,$hash{'title_'.$1});
                   4059:        }
                   4060:    }
                   4061:    &untiehash();
1.442     www      4062:    $r->print('<p class="LC_success">'.&mt('Done').'</p>');
1.521     bisitz   4063:     $r->print(&endContentScreen());
1.329     droeschl 4064: }
                   4065: 
                   4066: 
                   4067: sub devalidateversioncache {
                   4068:     my $src=shift;
                   4069:     &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
                   4070: 					  &Apache::lonnet::clutter($src));
                   4071: }
                   4072: 
                   4073: sub checkversions {
                   4074:     my ($r) = @_;
1.408     raeburn  4075:     my $crstype = &Apache::loncommon::course_type();
1.571     raeburn  4076:     $r->print(&Apache::loncommon::start_page("Check $crstype Resource Versions"));
                   4077:     $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Resource Versions"));
1.484     raeburn  4078:     $r->print(&startContentScreen('tools'));
1.442     www      4079: 
1.329     droeschl 4080:     my $header='';
                   4081:     my $startsel='';
                   4082:     my $monthsel='';
                   4083:     my $weeksel='';
                   4084:     my $daysel='';
                   4085:     my $allsel='';
                   4086:     my %changes=();
                   4087:     my $starttime=0;
                   4088:     my $haschanged=0;
                   4089:     my %setversions=&Apache::lonnet::dump('resourceversions',
                   4090: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   4091: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
                   4092: 
                   4093:     $hashtied=0;
                   4094:     &tiehash();
                   4095:     my %newsetversions=();
                   4096:     if ($env{'form.setmostrecent'}) {
                   4097: 	$haschanged=1;
                   4098: 	foreach my $key (keys(%hash)) {
                   4099: 	    if ($key=~/^ids\_(\/res\/.+)$/) {
                   4100: 		$newsetversions{$1}='mostrecent';
                   4101:                 &devalidateversioncache($1);
                   4102: 	    }
                   4103: 	}
                   4104:     } elsif ($env{'form.setcurrent'}) {
                   4105: 	$haschanged=1;
                   4106: 	foreach my $key (keys(%hash)) {
                   4107: 	    if ($key=~/^ids\_(\/res\/.+)$/) {
                   4108: 		my $getvers=&Apache::lonnet::getversion($1);
                   4109: 		if ($getvers>0) {
                   4110: 		    $newsetversions{$1}=$getvers;
                   4111: 		    &devalidateversioncache($1);
                   4112: 		}
                   4113: 	    }
                   4114: 	}
                   4115:     } elsif ($env{'form.setversions'}) {
                   4116: 	$haschanged=1;
                   4117: 	foreach my $key (keys(%env)) {
                   4118: 	    if ($key=~/^form\.set_version_(.+)$/) {
                   4119: 		my $src=$1;
                   4120: 		if (($env{$key}) && ($env{$key} ne $setversions{$src})) {
                   4121: 		    $newsetversions{$src}=$env{$key};
                   4122: 		    &devalidateversioncache($src);
                   4123: 		}
                   4124: 	    }
                   4125: 	}
                   4126:     }
                   4127:     if ($haschanged) {
                   4128:         if (&Apache::lonnet::put('resourceversions',\%newsetversions,
                   4129: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
1.344     bisitz   4130: 			  $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {
1.479     golterma 4131: 	    $r->print(&Apache::loncommon::confirmwrapper(
                   4132:                 &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved'))));
1.329     droeschl 4133: 	} else {
1.479     golterma 4134: 	    $r->print(&Apache::loncommon::confirmwrapper(
                   4135:                 &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1)));
1.329     droeschl 4136: 	}
                   4137: 	&mark_hash_old();
                   4138:     }
                   4139:     &changewarning($r,'');
                   4140:     if ($env{'form.timerange'} eq 'all') {
                   4141: # show all documents
1.549     raeburn  4142: 	$header=&mt('All content in '.$crstype);
1.521     bisitz   4143: 	$allsel=' selected="selected"';
1.329     droeschl 4144: 	foreach my $key (keys(%hash)) {
                   4145: 	    if ($key=~/^ids\_(\/res\/.+)$/) {
                   4146: 		my $src=$1;
                   4147: 		$changes{$src}=1;
                   4148: 	    }
                   4149: 	}
                   4150:     } else {
                   4151: # show documents which changed
                   4152: 	%changes=&Apache::lonnet::dump
                   4153: 	 ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
                   4154:                      $env{'course.'.$env{'request.course.id'}.'.num'});
                   4155: 	my $firstkey=(keys(%changes))[0];
                   4156: 	unless ($firstkey=~/^error\:/) {
                   4157: 	    unless ($env{'form.timerange'}) {
                   4158: 		$env{'form.timerange'}=604800;
                   4159: 	    }
                   4160: 	    my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
                   4161: 		.&mt('seconds');
                   4162: 	    if ($env{'form.timerange'}==-1) {
                   4163: 		$seltext='since start of course';
1.521     bisitz   4164: 		$startsel=' selected="selected"';
1.329     droeschl 4165: 		$env{'form.timerange'}=time;
                   4166: 	    }
                   4167: 	    $starttime=time-$env{'form.timerange'};
                   4168: 	    if ($env{'form.timerange'}==2592000) {
                   4169: 		$seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
1.521     bisitz   4170: 		$monthsel=' selected="selected"';
1.329     droeschl 4171: 	    } elsif ($env{'form.timerange'}==604800) {
                   4172: 		$seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
1.521     bisitz   4173: 		$weeksel=' selected="selected"';
1.329     droeschl 4174: 	    } elsif ($env{'form.timerange'}==86400) {
                   4175: 		$seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
1.521     bisitz   4176: 		$daysel=' selected="selected"';
1.329     droeschl 4177: 	    }
                   4178: 	    $header=&mt('Content changed').' '.$seltext;
                   4179: 	} else {
                   4180: 	    $header=&mt('No content modifications yet.');
                   4181: 	}
                   4182:     }
                   4183:     %setversions=&Apache::lonnet::dump('resourceversions',
                   4184: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   4185: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
                   4186:     my %lt=&Apache::lonlocal::texthash
1.408     raeburn  4187: 	      ('st' => 'Version changes since start of '.$crstype,
1.329     droeschl 4188: 	       'lm' => 'Version changes since last Month',
                   4189: 	       'lw' => 'Version changes since last Week',
                   4190: 	       'sy' => 'Version changes since Yesterday',
                   4191:                'al' => 'All Resources (possibly large output)',
1.484     raeburn  4192:                'cd' => 'Change display', 
1.329     droeschl 4193: 	       'sd' => 'Display',
                   4194: 	       'fi' => 'File',
                   4195: 	       'md' => 'Modification Date',
                   4196:                'mr' => 'Most recently published Version',
1.408     raeburn  4197: 	       've' => 'Version used in '.$crstype,
                   4198:                'vu' => 'Set Version to be used in '.$crstype,
                   4199: 'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below',
1.329     droeschl 4200: 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
                   4201: 'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
1.479     golterma 4202: 	       'di' => 'Differences',
1.484     raeburn  4203: 	       'save' => 'Save changes',
                   4204:                'vers' => 'Version choice(s) for specific resources', 
1.479     golterma 4205: 	       'act' => 'Actions');
1.329     droeschl 4206:     $r->print(<<ENDHEADERS);
1.484     raeburn  4207: <h4 class="LC_info">$header</h4>
1.329     droeschl 4208: <form action="/adm/coursedocs" method="post">
                   4209: <input type="hidden" name="versions" value="1" />
1.484     raeburn  4210: <div class="LC_left_float">
1.479     golterma 4211: <fieldset>
1.484     raeburn  4212: <legend>$lt{'cd'}</legend>
1.329     droeschl 4213: <select name="timerange">
1.521     bisitz   4214: <option value='all'$allsel>$lt{'al'}</option>
                   4215: <option value="-1"$startsel>$lt{'st'}</option>
                   4216: <option value="2592000"$monthsel>$lt{'lm'}</option>
                   4217: <option value="604800"$weeksel>$lt{'lw'}</option>
                   4218: <option value="86400"$daysel>$lt{'sy'}</option>
1.329     droeschl 4219: </select>
                   4220: <input type="submit" name="display" value="$lt{'sd'}" />
1.484     raeburn  4221: </fieldset>
                   4222: </div>
                   4223: <div class="LC_left_float">
                   4224: <fieldset>
                   4225: <legend>$lt{'act'}</legend>
                   4226: $lt{'sm'}: <input type="submit" name="setmostrecent" value="Go" /><br />
                   4227: $lt{'sc'}: <input type="submit" name="setcurrent" value="Go" />
                   4228: </fieldset>
                   4229: </div>
                   4230: <br clear="all" />
                   4231: <hr />
                   4232: <h4>$lt{'vers'}</h4>
1.329     droeschl 4233: ENDHEADERS
1.479     golterma 4234:     #number of columns for version history
1.571     raeburn  4235:     my %changedbytime;
                   4236:     foreach my $key (keys(%changes)) {
                   4237:         #excludes not versionable problems from resource version history:
                   4238:         next if ($key =~ /^\/res\/lib\/templates/);
                   4239:         my $chg;
                   4240:         if ($env{'form.timerange'} eq 'all') {
                   4241:             my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
                   4242:             $chg = &Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate');
                   4243:         } else {
                   4244:             $chg = $changes{$key};
                   4245:             next if ($chg < $starttime);
                   4246:         }
                   4247:         push(@{$changedbytime{$chg}},$key);
                   4248:     }
                   4249:     if (keys(%changedbytime) == 0) {
                   4250:         &untiehash();
                   4251:         $r->print(&mt('No content changes in imported content in specified time frame').
                   4252:                   &endContentScreen());
                   4253:         return;
                   4254:     }
1.479     golterma 4255:     $r->print(
1.571     raeburn  4256:        '<input type="submit" name="setversions" value="'.$lt{'save'}.'" />'.
1.521     bisitz   4257:         &Apache::loncommon::start_data_table().
                   4258:         &Apache::loncommon::start_data_table_header_row().
                   4259:         '<th>'.&mt('Resources').'</th>'.
                   4260:         "<th>$lt{'mr'}</th>".
                   4261:         "<th>$lt{'ve'}</th>".
                   4262:         "<th>$lt{'vu'}</th>".
                   4263:         '<th>'.&mt('History').'</th>'.
                   4264:         &Apache::loncommon::end_data_table_header_row()
                   4265:     );
1.571     raeburn  4266:     foreach my $chg (sort {$b <=> $a } keys(%changedbytime)) {
                   4267:         foreach my $key (sort(@{$changedbytime{$chg}})) {
                   4268:             my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
                   4269:             my $currentversion=&Apache::lonnet::getversion($key);
                   4270:             if ($currentversion<0) {
                   4271:                 $currentversion='<span class="LC_error">'.&mt('Could not be determined.').'</span>';
                   4272:             }
                   4273:             my $linkurl=&Apache::lonnet::clutter($key);
                   4274:             $r->print(
                   4275:                 &Apache::loncommon::start_data_table_row().
                   4276:                 '<td><b>'.&Apache::lonnet::gettitle($linkurl).'</b><br />'.
                   4277:                 '<a href="'.$linkurl.'" target="cat">'.$linkurl.'</a></td>'.
                   4278:                 '<td align="right">'.$currentversion.'<span class="LC_fontsize_medium"><br />('.
                   4279:                 &Apache::lonlocal::locallocaltime($chg).')</span></td>'.
                   4280:                 '<td align="right">'
                   4281:             );
                   4282:             # Used in course
                   4283:             my $usedversion=$hash{'version_'.$linkurl};
                   4284:             if (($usedversion) && ($usedversion ne 'mostrecent')) {
1.521     bisitz   4285:                 if ($usedversion != $currentversion) {
1.479     golterma 4286:                     $r->print('<span class="LC_warning">'.$usedversion.'</span>');
1.521     bisitz   4287:                 } else {
1.479     golterma 4288:                     $r->print($usedversion);
                   4289:                 }
1.329     droeschl 4290:             } else {
1.521     bisitz   4291:                 $r->print($currentversion);
1.329     droeschl 4292:             }
1.571     raeburn  4293:             $r->print('</td><td title="'.$lt{'vu'}.'">');
                   4294:             # Set version
                   4295:             $r->print(&Apache::loncommon::select_form(
                   4296:                       $setversions{$linkurl},
                   4297:                       'set_version_'.$linkurl,
                   4298:                       {'select_form_order' => ['',1..$currentversion,'mostrecent'],
                   4299:                       '' => '',
                   4300:                       'mostrecent' => &mt('most recent'),
                   4301:                       map {$_,$_} (1..$currentversion)}));
                   4302:             my $lastold=1;
                   4303:             for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
                   4304:                 my $url=$root.'.'.$prevvers.'.'.$extension;
                   4305:                 if (&Apache::lonnet::metadata($url,'lastrevisiondate')<$starttime) {
                   4306:                     $lastold=$prevvers;
                   4307:                 }
                   4308:             }
                   4309:             $r->print('</td>');
                   4310:             # List all available versions
                   4311:             $r->print('<td valign="top"><span class="LC_fontsize_medium">');
                   4312:             for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
                   4313:                 my $url=$root.'.'.$prevvers.'.'.$extension;
                   4314:                 $r->print(
                   4315:                     '<span class="LC_nobreak">'
                   4316:                    .'<a href="'.&Apache::lonnet::clutter($url).'">'
                   4317:                    .&mt('Version [_1]',$prevvers).'</a>'
                   4318:                    .' ('.&Apache::lonlocal::locallocaltime(
1.521     bisitz   4319:                          &Apache::lonnet::metadata($url,'lastrevisiondate'))
1.571     raeburn  4320:                    .')');
                   4321:                 if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
                   4322:                     $r->print(
                   4323:                         ' <a href="/adm/diff?filename='.
                   4324:                         &Apache::lonnet::clutter($root.'.'.$extension).
                   4325:                         &HTML::Entities::encode('&versionone='.$prevvers,'"<>&').
                   4326:                         '" target="diffs">'.&mt('Diffs').'</a>');
                   4327:                 }
                   4328:                 $r->print('</span><br />');
1.329     droeschl 4329:             }
1.571     raeburn  4330:             $r->print('</span></td>'.&Apache::loncommon::end_data_table_row());
1.521     bisitz   4331:         }
1.329     droeschl 4332:     }
1.521     bisitz   4333:     $r->print(
                   4334:         &Apache::loncommon::end_data_table().
                   4335:         '<input type="submit" name="setversions" value="'.$lt{'save'}.'" />'.
                   4336:         '</form>'
                   4337:     );
1.329     droeschl 4338: 
                   4339:     &untiehash();
1.521     bisitz   4340:     $r->print(&endContentScreen());
1.571     raeburn  4341:     return;
1.329     droeschl 4342: }
                   4343: 
                   4344: sub mark_hash_old {
                   4345:     my $retie_hash=0;
                   4346:     if ($hashtied) {
                   4347: 	$retie_hash=1;
                   4348: 	&untiehash();
                   4349:     }
                   4350:     &tiehash('write');
                   4351:     $hash{'old'}=1;
                   4352:     &untiehash();
                   4353:     if ($retie_hash) { &tiehash(); }
                   4354: }
                   4355: 
                   4356: sub is_hash_old {
                   4357:     my $untie_hash=0;
                   4358:     if (!$hashtied) {
                   4359: 	$untie_hash=1;
                   4360: 	&tiehash();
                   4361:     }
                   4362:     my $return=$hash{'old'};
                   4363:     if ($untie_hash) { &untiehash(); }
                   4364:     return $return;
                   4365: }
                   4366: 
                   4367: sub changewarning {
                   4368:     my ($r,$postexec,$message,$url)=@_;
                   4369:     if (!&is_hash_old()) { return; }
                   4370:     my $pathvar='folderpath';
                   4371:     my $path=&escape($env{'form.folderpath'});
                   4372:     if (!defined($url)) {
                   4373: 	$url='/adm/coursedocs?'.$pathvar.'='.$path;
                   4374:     }
                   4375:     my $course_type = &Apache::loncommon::course_type();
                   4376:     if (!defined($message)) {
                   4377: 	$message='Changes will become active for your current session after [_1], or the next time you log in.';
                   4378:     }
                   4379:     $r->print("\n\n".
1.372     bisitz   4380: '<script type="text/javascript">'."\n".
                   4381: '// <![CDATA['."\n".
                   4382: 'function reinit(tf) { tf.submit();'.$postexec.' }'."\n".
                   4383: '// ]]>'."\n".
1.369     bisitz   4384: '</script>'."\n".
1.375     tempelho 4385: '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'.
1.329     droeschl 4386: '<input type="hidden" name="orgurl" value="'.$url.
1.372     bisitz   4387: '" /><input type="hidden" name="selectrole" value="1" /><p class="LC_warning">'.
1.329     droeschl 4388: &mt($message,' <input type="hidden" name="'.
                   4389:     $env{'request.role'}.'" value="1" /><input type="button" value="'.
1.369     bisitz   4390:     &mt('re-initializing '.$course_type).'" onclick="reinit(this.form)" />').
1.372     bisitz   4391: $help{'Caching'}.'</p></form>'."\n\n");
1.329     droeschl 4392: }
                   4393: 
                   4394: 
                   4395: sub init_breadcrumbs {
1.571     raeburn  4396:     my ($form,$text,$help)=@_;
1.329     droeschl 4397:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.484     raeburn  4398:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1",
1.405     bisitz   4399: 					    text=>&Apache::loncommon::course_type().' Editor',
1.329     droeschl 4400: 					    faq=>273,
                   4401: 					    bug=>'Instructor Interface',
1.571     raeburn  4402:                                             help => $help});
1.329     droeschl 4403:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
                   4404: 					    text=>$text,
                   4405: 					    faq=>273,
                   4406: 					    bug=>'Instructor Interface'});
                   4407: }
                   4408: 
1.441     www      4409: # subroutine to list form elements
                   4410: sub create_list_elements {
                   4411:    my @formarr = @_;
                   4412:    my $list = '';
1.501     raeburn  4413:    foreach my $button (@formarr){
                   4414:         foreach my $picture (keys(%{$button})) {
                   4415:             $list .= &Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text', id => ''});
1.441     www      4416:         }
                   4417:    }
                   4418:    return $list;
                   4419: }
1.329     droeschl 4420: 
1.441     www      4421: # subroutine to create ul from list elements
                   4422: sub create_form_ul {
                   4423:    my $list = shift;
                   4424:    my $ul = &Apache::lonhtmlcommon::htmltag('ul',$list, {class => 'LC_ListStyleNormal'});
                   4425:    return $ul;
                   4426: }
1.329     droeschl 4427: 
1.442     www      4428: #
                   4429: # Start tabs
                   4430: #
                   4431: 
                   4432: sub startContentScreen {
1.484     raeburn  4433:     my ($mode) = @_;
                   4434:     my $output = '<ul class="LC_TabContentBigger" id="mainnav">';
1.472     raeburn  4435:     if (($mode eq 'navmaps') || ($mode eq 'supplemental')) {
1.484     raeburn  4436:         $output .= '<li'.(($mode eq 'navmaps')?' class="active"':'').'><a href="/adm/navmaps"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Overview').'&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n";
                   4437:         $output .= '<li'.(($mode eq 'coursesearch')?' class="active"':'').'><a href="/adm/searchcourse"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Search').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n";
                   4438:         $output .= '<li'.(($mode eq 'courseindex')?' class="active"':'').'><a href="/adm/indexcourse"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Index').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n";
                   4439:         $output .= '<li '.(($mode eq 'suppdocs')?' class="active"':'').'><a href="/adm/supplemental"><b>'.&mt('Supplemental Content').'</b></a></li>';
                   4440:     } else {
1.549     raeburn  4441:         $output .= '<li '.(($mode eq 'docs')?' class="active"':'').' id="tabbededitor"><a href="/adm/coursedocs?forcestandard=1"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Main Content Editor').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n";
1.484     raeburn  4442:         $output .= '<li '.(($mode eq 'suppdocs')?' class="active"':'').'><a href="/adm/coursedocs?forcesupplement=1"><b>'.&mt('Supplemental Content Editor').'</b></a></li>'."\n";
                   4443:         $output .= '<li '.(($mode eq 'tools')?' class="active"':'').'><a href="/adm/coursedocs?tools=1"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Utilities').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n";
                   4444:                    '><a href="/adm/coursedocs?tools=1"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Content Utilities').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>';
                   4445:     }
                   4446:     $output .= "\n".'</ul>'."\n";
                   4447:     $output .= '<div class="LC_DocsBox" style="clear:both;margin:0;" id="contenteditor">'.
                   4448:                '<div id="maincoursedoc" style="margin:0 0;padding:0 0;">'.
                   4449:                '<div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">';
                   4450:     return $output;
1.442     www      4451: }
                   4452: 
                   4453: #
                   4454: # End tabs
                   4455: #
                   4456: 
                   4457: sub endContentScreen {
1.484     raeburn  4458:     return '</div></div></div>';
1.442     www      4459: }
1.329     droeschl 4460: 
1.446     www      4461: sub supplemental_base {
1.548     raeburn  4462:     return 'supplemental&'.&escape(&mt('Supplemental Content'));
1.446     www      4463: }
                   4464: 
1.329     droeschl 4465: sub handler {
                   4466:     my $r = shift;
                   4467:     &Apache::loncommon::content_type($r,'text/html');
                   4468:     $r->send_http_header;
                   4469:     return OK if $r->header_only;
1.484     raeburn  4470: 
                   4471: # get course data
1.408     raeburn  4472:     my $crstype = &Apache::loncommon::course_type();
1.484     raeburn  4473:     my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
                   4474:     my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                   4475: 
                   4476: # graphics settings
                   4477:     $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL').'/');
1.329     droeschl 4478: 
1.443     www      4479: #
1.329     droeschl 4480: # --------------------------------------------- Initialize help topics for this
                   4481:     foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
                   4482: 	               'Adding_External_Resource','Navigate_Content',
                   4483: 	               'Adding_Folders','Docs_Overview', 'Load_Map',
                   4484: 	               'Supplemental','Score_Upload_Form','Adding_Pages',
1.501     raeburn  4485: 	               'Importing_LON-CAPA_Resource','Importing_IMS_Course',
1.571     raeburn  4486:                        'Uploading_From_Harddrive','Course_Roster','Web_Page',
1.572     raeburn  4487:                        'Dropbox','Simple_Problem') {
1.329     droeschl 4488: 	$help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
                   4489:     }
                   4490:     # Composite help files
                   4491:     $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
                   4492: 		    'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
                   4493:     $help{'Simple Page'} = &Apache::loncommon::help_open_topic(
                   4494: 		    'Docs_About_Simple_Page,Docs_Editing_Templated_Pages');
                   4495:     $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
                   4496: 		    'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
1.347     weissno  4497:     $help{'My Personal Information Page'} = &Apache::loncommon::help_open_topic(
1.329     droeschl 4498: 		  'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
1.353     weissno  4499:     $help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
1.329     droeschl 4500:     $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
1.534     raeburn  4501:  
1.472     raeburn  4502:     my $allowed;
                   4503: # URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
                   4504:     unless ($r->uri eq '/adm/supplemental') {
                   4505:         # does this user have privileges to modify content.  
                   4506:         $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                   4507:     }
                   4508: 
1.582     raeburn  4509:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['inhibitmenu']);
                   4510:   if ($allowed && $env{'form.verify'}) {
1.571     raeburn  4511:       &init_breadcrumbs('verify','Verify Content','Docs_Verify_Content');
1.329     droeschl 4512:       &verifycontent($r);
                   4513:   } elsif ($allowed && $env{'form.listsymbs'}) {
1.484     raeburn  4514:       &init_breadcrumbs('listsymbs','List Content IDs');
1.329     droeschl 4515:       &list_symbs($r);
                   4516:   } elsif ($allowed && $env{'form.docslog'}) {
                   4517:       &init_breadcrumbs('docslog','Show Log');
1.484     raeburn  4518:       my $folder = $env{'form.folder'};
                   4519:       if ($folder eq '') {
                   4520:           $folder='default';
                   4521:       }
                   4522:       &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath);
1.329     droeschl 4523:   } elsif ($allowed && $env{'form.versions'}) {
1.571     raeburn  4524:       &init_breadcrumbs('versions','Check/Set Resource Versions','Docs_Check_Resource_Versions');
1.329     droeschl 4525:       &checkversions($r);
                   4526:   } elsif ($allowed && $env{'form.dumpcourse'}) {
1.568     raeburn  4527:       &init_breadcrumbs('dumpcourse','Copy '.&Apache::loncommon::course_type().' Content to Authoring Space');
1.329     droeschl 4528:       &dumpcourse($r);
                   4529:   } elsif ($allowed && $env{'form.exportcourse'}) {
1.377     bisitz   4530:       &init_breadcrumbs('exportcourse','IMS Export');
1.475     raeburn  4531:       &Apache::imsexport::exportcourse($r);
1.329     droeschl 4532:   } else {
1.445     www      4533: #
                   4534: # Done catching special calls
1.484     raeburn  4535: # The whole rest is for course and supplemental documents and utilities menu
1.445     www      4536: # Get the parameters that may be needed
                   4537: #
                   4538:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.519     raeburn  4539:                                             ['folderpath',
                   4540:                                              'forcesupplement','forcestandard',
1.510     raeburn  4541:                                              'tools','symb','command','supppath']);
1.445     www      4542: 
                   4543: # standard=1: this is a "new-style" course with an uploaded map as top level
                   4544: # standard=2: this is a "old-style" course, and there is nothing we can do
1.329     droeschl 4545: 
                   4546:     my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
1.445     www      4547: 
1.484     raeburn  4548: # Decide whether this should display supplemental or main content or utilities
1.445     www      4549: # supplementalflag=1: show supplemental documents
                   4550: # supplementalflag=0: show standard documents
1.484     raeburn  4551: # toolsflag=1: show utilities
1.445     www      4552: 
1.561     raeburn  4553:     my $unesc_folderpath = &unescape($env{'form.folderpath'});
                   4554:     my $supplementalflag=($unesc_folderpath=~/^supplemental/);
                   4555:     if (($unesc_folderpath=~/^default/) || ($unesc_folderpath eq "")) {
1.445     www      4556:        $supplementalflag=0;
                   4557:     }
                   4558:     if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
                   4559:     if ($env{'form.forcestandard'})   { $supplementalflag=0; }
                   4560:     unless ($allowed) { $supplementalflag=1; }
                   4561:     unless ($standard) { $supplementalflag=1; }
1.484     raeburn  4562:     my $toolsflag=0;
                   4563:     if ($env{'form.tools'}) { $toolsflag=1; }
1.445     www      4564: 
1.329     droeschl 4565:     my $script='';
                   4566:     my $showdoc=0;
1.457     raeburn  4567:     my $addentries = {};
1.475     raeburn  4568:     my $container;
1.329     droeschl 4569:     my $containertag;
1.508     raeburn  4570:     my $pathitem;
1.329     droeschl 4571: 
1.464     www      4572: # Do we directly jump somewhere?
1.466     www      4573: 
1.525     raeburn  4574:    if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) {
1.472     raeburn  4575:        if ($env{'form.symb'} ne '') {
1.522     raeburn  4576:            $env{'form.folderpath'}=
                   4577:                &Apache::loncommon::symb_to_docspath($env{'form.symb'});
1.530     raeburn  4578:            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
1.525     raeburn  4579:                $env{'form.command'}.'_'.$env{'form.symb'}});
1.472     raeburn  4580:        } elsif ($env{'form.supppath'} ne '') {
                   4581:            $env{'form.folderpath'}=$env{'form.supppath'};
1.530     raeburn  4582:            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
1.525     raeburn  4583:                $env{'form.command'}.'_'.$env{'form.supppath'}});
1.466     www      4584:        }
1.472     raeburn  4585:    } elsif ($env{'form.command'} eq 'editdocs') {
1.525     raeburn  4586:        $env{'form.folderpath'} = 'default&'.
1.548     raeburn  4587:                                  &escape(&mt('Main Content').':::::');
1.525     raeburn  4588:        &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}});
1.472     raeburn  4589:    } elsif ($env{'form.command'} eq 'editsupp') {
1.525     raeburn  4590:        $env{'form.folderpath'} = 'supplemental&'.
1.538     raeburn  4591:                                   &escape('Supplemental Content');
1.525     raeburn  4592:        &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'});
                   4593:    } elsif ($env{'form.command'} eq 'contents') {
                   4594:        &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'});
                   4595:    } elsif ($env{'form.command'} eq 'home') {
                   4596:        &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/menu'});
1.464     www      4597:    }
                   4598: 
1.525     raeburn  4599: 
1.445     www      4600: # Where do we store these for when we come back?
                   4601:     my $stored_folderpath='docs_folderpath';
                   4602:     if ($supplementalflag) {
                   4603:        $stored_folderpath='docs_sup_folderpath';
                   4604:     }
1.464     www      4605: 
1.519     raeburn  4606: # No folderpath, and in edit mode, see if we have something stored
                   4607:     if ((!$env{'form.folderpath'}) && $allowed) {
1.445     www      4608:         &Apache::loncommon::restore_course_settings($stored_folderpath,
1.510     raeburn  4609:                                           {'folderpath' => 'scalar'});
1.523     raeburn  4610:         unless (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) {
                   4611:             undef($env{'form.folderpath'});
                   4612:         }
1.329     droeschl 4613:     }
1.446     www      4614:    
                   4615: # If we are not allowed to make changes, all we can see are supplemental docs
1.409     raeburn  4616:     if (!$allowed) {
1.446     www      4617:         unless ($env{'form.folderpath'} =~ /^supplemental/) {
                   4618:             $env{'form.folderpath'} = &supplemental_base();
1.409     raeburn  4619:         }
                   4620:     }
1.446     www      4621: # Make the zeroth entry in supplemental docs page paths, so we can get to top level
1.329     droeschl 4622:     if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
1.446     www      4623:         $env{'form.folderpath'} = &supplemental_base()
                   4624:                                   .'&'.
1.329     droeschl 4625:                                   $env{'form.folderpath'};
                   4626:     }
1.446     www      4627: # If after all of this, we still don't have any paths, make them
1.519     raeburn  4628:     unless ($env{'form.folderpath'}) {
1.446     www      4629:        if ($supplementalflag) {
                   4630:           $env{'form.folderpath'}=&supplemental_base();
                   4631:        } else {
1.548     raeburn  4632:           $env{'form.folderpath'}='default&'.&escape(&mt('Main Content').
1.538     raeburn  4633:                                   ':::::');
1.446     www      4634:        }
1.472     raeburn  4635:     }
1.446     www      4636: 
1.445     www      4637: # Store this
1.484     raeburn  4638:     unless ($toolsflag) {
1.510     raeburn  4639:         if ($allowed) {
                   4640:             &Apache::loncommon::store_course_settings($stored_folderpath,
1.519     raeburn  4641:                                                       {'folderpath' => 'scalar'});
1.510     raeburn  4642:         }
1.519     raeburn  4643:         my $folderpath;
1.484     raeburn  4644:         if ($env{'form.folderpath'}) {
1.519     raeburn  4645:             $folderpath = $env{'form.folderpath'};
                   4646: 	    my (@folders)=split('&',$env{'form.folderpath'});
                   4647: 	    $env{'form.foldername'}=&unescape(pop(@folders));
                   4648:             if ($env{'form.foldername'} =~ /\:1$/) {
                   4649:                 $container = 'page';
                   4650:             } else {
                   4651:                 $container = 'sequence';
                   4652:             }
                   4653: 	    $env{'form.folder'}=pop(@folders);
1.484     raeburn  4654:         } else {
1.519     raeburn  4655:             if ($env{'form.folder'} eq '' ||
                   4656:                 $env{'form.folder'} eq 'supplemental') {
                   4657:                 $folderpath='default&'.
1.548     raeburn  4658:                             &escape(&mt('Main Content').':::::');
1.484     raeburn  4659:             }
                   4660:         }
1.519     raeburn  4661:         $containertag = '<input type="hidden" name="folderpath" value="" />';
                   4662:         $pathitem = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />';
1.484     raeburn  4663:         if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
                   4664:            $showdoc='/'.$1;
                   4665:         }
                   4666:         if ($showdoc) { # got called in sequence from course
                   4667: 	    $allowed=0; 
                   4668:         } else {
                   4669:             if ($allowed) {
                   4670:                 &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
                   4671:                 $script=&Apache::lonratedt::editscript('simple');
1.433     raeburn  4672:             }
                   4673:         }
1.329     droeschl 4674:     }
                   4675: 
1.344     bisitz   4676: # get personal data
1.329     droeschl 4677:     my $uname=$env{'user.name'};
                   4678:     my $udom=$env{'user.domain'};
                   4679:     my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom));
                   4680: 
                   4681:     if ($allowed) {
1.484     raeburn  4682:         if ($toolsflag) {
                   4683:             $script .= &inject_data_js();
                   4684:             my ($home,$other,%outhash)=&authorhosts();
                   4685:             if (!$home && $other) {
                   4686:                 my @hosts;
                   4687:                 foreach my $aurole (keys(%outhash)) {
                   4688:                     unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) {
                   4689:                         push(@hosts,$outhash{$aurole});
                   4690:                     }
                   4691:                 }
                   4692:                 $script .= &dump_switchserver_js(@hosts); 
                   4693:             }
1.458     raeburn  4694:         } else {
1.570     raeburn  4695:             my $tid = 1;
1.484     raeburn  4696:             my @tabids;
                   4697:             if ($supplementalflag) {
                   4698:                 @tabids = ('002','ee2','ff2');
1.570     raeburn  4699:                 $tid = 2;
1.484     raeburn  4700:             } else {
                   4701:                 @tabids = ('aa1','bb1','cc1','ff1');
1.519     raeburn  4702:                 unless ($env{'form.folderpath'} =~ /\:1$/) {
1.484     raeburn  4703:                     unshift(@tabids,'001');
                   4704:                     push(@tabids,('dd1','ee1'));
                   4705:                 }
1.458     raeburn  4706:             }
1.484     raeburn  4707:             my $tabidstr = join("','",@tabids);
                   4708: 	    $script .= &editing_js($udom,$uname,$supplementalflag).
                   4709:                        &history_tab_js().
                   4710:                        &inject_data_js().
1.570     raeburn  4711:                        &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).
1.510     raeburn  4712:                        &Apache::lonextresedit::extedit_javascript();
1.484     raeburn  4713:             $addentries = {
1.485     raeburn  4714:                             onload   => "javascript:resize_scrollbox('contentscroll','1','1');",
1.484     raeburn  4715:                           };
1.458     raeburn  4716:         }
1.538     raeburn  4717:         $script .= &paste_popup_js(); 
1.501     raeburn  4718:         my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'.
                   4719:                              &mt('Switch server?');
                   4720:         
                   4721: 
1.329     droeschl 4722:     }
                   4723: # -------------------------------------------------------------------- Body tag
1.369     bisitz   4724:     $script = '<script type="text/javascript">'."\n"
1.372     bisitz   4725:               .'// <![CDATA['."\n"
                   4726:               .$script."\n"
                   4727:               .'// ]]>'."\n"
                   4728:               .'</script>'."\n";
1.385     bisitz   4729: 
                   4730:     # Breadcrumbs
                   4731:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.510     raeburn  4732: 
                   4733:     if ($showdoc) {
                   4734:         $r->print(&Apache::loncommon::start_page("$crstype documents",undef,
                   4735:                                                 {'force_register' => $showdoc,}));
1.571     raeburn  4736:     } elsif ($toolsflag) {
                   4737:         &Apache::lonhtmlcommon::add_breadcrumb({
                   4738:             href=>"/adm/coursedocs",text=>"$crstype Contents"});
                   4739:         $r->print(&Apache::loncommon::start_page("$crstype Contents", $script)
                   4740:                  .&Apache::loncommon::help_open_menu('','',273,'RAT')
                   4741:                  .&Apache::lonhtmlcommon::breadcrumbs(
                   4742:                      'Editing Course Contents')
                   4743:                  );
1.510     raeburn  4744:     } elsif ($r->uri eq '/adm/supplemental') {
                   4745:         my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);
                   4746:         $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,
                   4747:                                                 {'bread_crumbs' => $brcrum,}));
                   4748:     } else {
1.392     raeburn  4749:         &Apache::lonhtmlcommon::add_breadcrumb({
1.446     www      4750:             href=>"/adm/coursedocs",text=>"$crstype Contents"});
                   4751:         $r->print(&Apache::loncommon::start_page("$crstype Contents", $script,
1.510     raeburn  4752:                                                  {'add_entries'    => $addentries}
                   4753:                                                 )
1.392     raeburn  4754:                  .&Apache::loncommon::help_open_menu('','',273,'RAT')
                   4755:                  .&Apache::lonhtmlcommon::breadcrumbs(
1.484     raeburn  4756:                      'Editing '.$crstype.' Contents',
1.392     raeburn  4757:                      'Docs_Adding_Course_Doc')
                   4758:         );
                   4759:     }
1.364     bisitz   4760: 
1.329     droeschl 4761:   my %allfiles = ();
                   4762:   my %codebase = ();
1.440     raeburn  4763:   my ($upload_result,$upload_output,$uploadphase);
1.329     droeschl 4764:   if ($allowed) {
                   4765:       if (($env{'form.uploaddoc.filename'}) &&
                   4766: 	  ($env{'form.cmd'}=~/^upload_(\w+)/)) {
1.440     raeburn  4767:           my $context = $1; 
                   4768:           # Process file upload - phase one - upload and parse primary file.
1.329     droeschl 4769: 	  undef($hadchanges);
1.440     raeburn  4770:           $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom,
1.552     raeburn  4771:                                               \%allfiles,\%codebase,$context,$crstype);
1.329     droeschl 4772: 	  if ($hadchanges) {
                   4773: 	      &mark_hash_old();
                   4774: 	  }
1.440     raeburn  4775:           $r->print($upload_output);
                   4776:       } elsif ($env{'form.phase'} eq 'upload_embedded') {
                   4777:           # Process file upload - phase two - upload embedded objects 
                   4778:           $uploadphase = 'check_embedded';
                   4779:           my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"');   
                   4780:           my $state = &embedded_form_elems($uploadphase,$primaryurl,
                   4781:                                            $env{'form.newidx'});
                   4782:           my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
                   4783:           my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                   4784:           my ($destination,$dir_root) = &embedded_destination();
                   4785:           my $url_root = '/uploaded/'.$docudom.'/'.$docuname;
                   4786:           my $actionurl = '/adm/coursedocs';
                   4787:           my ($result,$flag) = 
                   4788:               &Apache::loncommon::upload_embedded('coursedoc',$destination,
                   4789:                   $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state,
                   4790:                   $actionurl);
                   4791:           $r->print($result.&return_to_editor());
                   4792:       } elsif ($env{'form.phase'} eq 'check_embedded') {
                   4793:           # Process file upload - phase three - modify references in HTML file
                   4794:           $uploadphase = 'modified_orightml';
                   4795:           my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
                   4796:           my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                   4797:           my ($destination,$dir_root) = &embedded_destination();
1.482     raeburn  4798:           my $result = 
                   4799:               &Apache::loncommon::modify_html_refs('coursedoc',$destination,
                   4800:                                                    $docuname,$docudom,undef,
                   4801:                                                    $dir_root);
                   4802:           $r->print($result.&return_to_editor());   
1.476     raeburn  4803:       } elsif ($env{'form.phase'} eq 'decompress_uploaded') {
                   4804:           $uploadphase = 'decompress_phase_one';
                   4805:           $r->print(&decompression_phase_one().
                   4806:                     &return_to_editor());
                   4807:       } elsif ($env{'form.phase'} eq 'decompress_cleanup') {
                   4808:           $uploadphase = 'decompress_phase_two';
                   4809:           $r->print(&decompression_phase_two().
                   4810:                     &return_to_editor());
1.329     droeschl 4811:       }
                   4812:   }
                   4813: 
1.484     raeburn  4814:   if ($allowed && $toolsflag) {
                   4815:       $r->print(&startContentScreen('tools'));
                   4816:       $r->print(&generate_admin_menu($crstype));
                   4817:       $r->print(&endContentScreen());
                   4818:   } elsif ((!$showdoc) && (!$uploadphase)) {
1.329     droeschl 4819: # -----------------------------------------------------------------------------
                   4820:        my %lt=&Apache::lonlocal::texthash(
                   4821: 		'copm' => 'All documents out of a published map into this folder',
1.501     raeburn  4822:                 'upfi' => 'Upload File',
1.553     raeburn  4823:                 'upld' => 'Upload Content',
1.329     droeschl 4824:                 'srch' => 'Search',
                   4825:                 'impo' => 'Import',
1.487     raeburn  4826: 		'lnks' => 'Import from Stored Links',
1.502     raeburn  4827:                 'impm' => 'Import from Assembled Map',
1.329     droeschl 4828:                 'selm' => 'Select Map',
                   4829:                 'load' => 'Load Map',
                   4830:                 'newf' => 'New Folder',
                   4831:                 'newp' => 'New Composite Page',
                   4832:                 'syll' => 'Syllabus',
1.425     raeburn  4833:                 'navc' => 'Table of Contents',
1.343     biermanm 4834:                 'sipa' => 'Simple Course Page',
1.329     droeschl 4835:                 'sipr' => 'Simple Problem',
1.534     raeburn  4836:                 'webp' => 'Blank Web Page (editable)', 
1.329     droeschl 4837:                 'drbx' => 'Drop Box',
1.451     www      4838:                 'scuf' => 'External Scores (handgrade, upload, clicker)',
1.336     schafran 4839:                 'bull' => 'Discussion Board',
1.347     weissno  4840:                 'mypi' => 'My Personal Information Page',
1.353     weissno  4841:                 'grpo' => 'Group Portfolio',
1.329     droeschl 4842:                 'rost' => 'Course Roster',
1.528     raeburn  4843:                 'abou' => 'Personal Information Page for a User',
1.553     raeburn  4844:                 'imsf' => 'IMS Upload',
                   4845:                 'imsl' => 'Upload IMS package',
1.501     raeburn  4846:                 'cms'  => 'Origin of IMS package',
                   4847:                 'se'   => 'Select',
1.329     droeschl 4848:                 'file' =>  'File',
                   4849:                 'title' => 'Title',
                   4850:                 'comment' => 'Comment',
1.403     raeburn  4851:                 'parse' => 'Upload embedded images/multimedia files if HTML file',
1.577     bisitz   4852:                 'bb5'      => 'Blackboard 5',
                   4853:                 'bb6'      => 'Blackboard 6',
                   4854:                 'angel5'   => 'ANGEL 5.5',
                   4855:                 'webctce4' => 'WebCT 4 Campus Edition',
                   4856:         );
1.329     droeschl 4857: # -----------------------------------------------------------------------------
                   4858: 	my $fileupload=(<<FIUP);
                   4859: 	$lt{'file'}:<br />
                   4860: 	<input type="file" name="uploaddoc" size="40" />
                   4861: FIUP
                   4862: 
                   4863: 	my $checkbox=(<<CHBO);
                   4864: 	<!-- <label>$lt{'parse'}?
                   4865: 	<input type="checkbox" name="parserflag" />
                   4866: 	</label> -->
                   4867: 	<label>
                   4868: 	<input type="checkbox" name="parserflag" checked="checked" /> $lt{'parse'}
                   4869: 	</label>
                   4870: CHBO
1.501     raeburn  4871:         my $imsfolder = $env{'form.folder'};
                   4872:         if ($imsfolder eq '') {
                   4873:             $imsfolder = 'default';  
                   4874:         }
                   4875:         my $imspform=(<<IMSFORM);
                   4876:         <a class="LC_menubuttons_link" href="javascript:toggleUpload('ims');">
                   4877:         $lt{'imsf'}</a> $help{'Importing_IMS_Course'}
                   4878:         <form name="uploadims" action="/adm/imsimportdocs" method="post" enctype="multipart/form-data" target="IMSimport">
1.516     raeburn  4879:         <fieldset id="uploadimsform" style="display: none;">
1.501     raeburn  4880:         <legend>$lt{'imsf'}</legend>
                   4881:         $fileupload
                   4882:         <br />
                   4883:         <p>
                   4884:         $lt{'cms'}:&nbsp; 
                   4885:         <select name="source">
                   4886:         <option value="-1" selected="selected">$lt{'se'}</option>
1.577     bisitz   4887:         <option value="bb5">$lt{'bb5'}</option>
                   4888:         <option value="bb6">$lt{'bb6'}</option>
                   4889:         <option value="angel5">$lt{'angel5'}</option>
                   4890:         <option value="webctce4">$lt{'webctce4'}</option>
1.501     raeburn  4891:         </select>
                   4892:         <input type="hidden" name="folder" value="$imsfolder" />
                   4893:         </p>
                   4894:         <input type="hidden" name="phase" value="one" />
                   4895:         <input type="button" value="$lt{'imsl'}" onclick="makeims(this.form);" />
                   4896:         </fieldset>
                   4897:         </form>
                   4898: IMSFORM
1.329     droeschl 4899: 
                   4900: 	my $fileuploadform=(<<FUFORM);
1.501     raeburn  4901:         <a class="LC_menubuttons_link" href="javascript:toggleUpload('doc');">
                   4902:         $lt{'upfi'}</a> $help{'Uploading_From_Harddrive'}
                   4903:         <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.516     raeburn  4904:         <fieldset id="uploaddocform" style="display: none;">
1.501     raeburn  4905:         <legend>$lt{'upfi'}</legend>
1.371     tempelho 4906: 	<input type="hidden" name="active" value="aa" />
1.329     droeschl 4907: 	$fileupload
                   4908: 	<br />
                   4909: 	$lt{'title'}:<br />
1.458     raeburn  4910: 	<input type="text" size="60" name="comment" />
1.508     raeburn  4911: 	$pathitem
1.329     droeschl 4912: 	<input type="hidden" name="cmd" value="upload_default" />
                   4913: 	<br />
1.458     raeburn  4914: 	<span class="LC_nobreak" style="float:left">
1.329     droeschl 4915: 	$checkbox
                   4916: 	</span>
1.501     raeburn  4917:         <br clear="all" />
                   4918:         <input type="submit" value="$lt{'upld'}" />
                   4919:         </fieldset>
                   4920:         </form>
1.383     tempelho 4921: FUFORM
1.329     droeschl 4922: 
1.502     raeburn  4923: 	my $importpubform=(<<SEDFFORM);
1.514     raeburn  4924:         <a class="LC_menubuttons_link" href="javascript:toggleMap('map');">
1.502     raeburn  4925:         $lt{'impm'}</a>$help{'Load_Map'}
                   4926: 	<form action="/adm/coursedocs" method="post" name="mapimportform">
1.516     raeburn  4927:         <fieldset id="importmapform" style="display: none;">
1.502     raeburn  4928:         <legend>$lt{'impm'}</legend>
1.371     tempelho 4929: 	<input type="hidden" name="active" value="bb" />
1.502     raeburn  4930:         $lt{'copm'}<br />
                   4931:         <span class="LC_nobreak">
                   4932:         <input type="text" name="importmap" size="40" value="" 
                   4933:         onfocus="this.blur();openbrowser('mapimportform','importmap','sequence,page','');" />
1.516     raeburn  4934:         &nbsp;<a href="javascript:openbrowser('mapimportform','importmap','sequence,page','');">$lt{'selm'}</a></span><br />
1.502     raeburn  4935:         <input type="submit" name="loadmap" value="$lt{'load'}" />
                   4936:         </fieldset>
                   4937:         </form>
                   4938: 
1.383     tempelho 4939: SEDFFORM
1.502     raeburn  4940: 	my @importpubforma = (
1.508     raeburn  4941: 	{ '<img class="LC_noBorder LC_middle" src="/res/adm/pages/src.png" alt="'.$lt{srch}.'"  onclick="javascript:groupsearch()" />' => $pathitem."<a class='LC_menubuttons_link' href='javascript:groupsearch()'>$lt{'srch'}</a>" },
1.423     onken    4942: 	{ '<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'}" },
1.487     raeburn  4943: 	{ '<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>" },
1.514     raeburn  4944:         { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/sequence.png" alt="'.$lt{impm}.'" onclick="javascript:toggleMap(\'map\');" />' => $importpubform }
1.383     tempelho 4945: 	);
1.502     raeburn  4946: 	$importpubform = &create_form_ul(&create_list_elements(@importpubforma));
1.510     raeburn  4947:         my $extresourcesform =
                   4948:             &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem,
                   4949:                                                  $help{'Adding_External_Resource'});
1.329     droeschl 4950:     if ($allowed) {
1.492     raeburn  4951:         my $folder = $env{'form.folder'};
                   4952:         if ($folder eq '') {
                   4953:             $folder='default';
                   4954:         }
1.538     raeburn  4955: 	my $output = &update_paste_buffer($coursenum,$coursedom,$folder);
                   4956:         if ($output) {
                   4957:             $r->print($output);
                   4958:         }
1.337     ehlerst  4959: 	$r->print(<<HIDDENFORM);
                   4960: 	<form name="renameform" method="post" action="/adm/coursedocs">
                   4961:    <input type="hidden" name="title" />
                   4962:    <input type="hidden" name="cmd" />
                   4963:    <input type="hidden" name="markcopy" />
                   4964:    <input type="hidden" name="copyfolder" />
                   4965:    $containertag
                   4966:  </form>
1.484     raeburn  4967: 
1.337     ehlerst  4968: HIDDENFORM
1.508     raeburn  4969:         $r->print(&makesimpleeditform($pathitem)."\n".
                   4970:                   &makedocslogform($pathitem."\n".
1.484     raeburn  4971:                                    '<input type="hidden" name="folder" value="'.
                   4972:                                    $env{'form.folder'}.'" />'."\n"));
1.329     droeschl 4973:     }
1.442     www      4974: 
                   4975: # Generate the tabs
1.510     raeburn  4976:     my ($mode,$needs_end);
1.472     raeburn  4977:     if (($supplementalflag) && (!$allowed)) {
1.510     raeburn  4978:         my @folders = split('&',$env{'form.folderpath'});
                   4979:         unless (@folders > 2) {
                   4980:             &Apache::lonnavdisplay::startContentScreen($r,'supplemental');
                   4981:             $needs_end = 1;
                   4982:         }
1.472     raeburn  4983:     } else {
1.484     raeburn  4984:         $r->print(&startContentScreen(($supplementalflag?'suppdocs':'docs')));
1.510     raeburn  4985:         $needs_end = 1;
1.472     raeburn  4986:     }
1.443     www      4987: 
1.442     www      4988: #
                   4989: 
                   4990:     my $savefolderpath;
                   4991: 
1.395     raeburn  4992:     if ($allowed) {
1.329     droeschl 4993:        my $folder=$env{'form.folder'};
1.443     www      4994:        if ($folder eq '' || $supplementalflag) {
1.329     droeschl 4995:            $folder='default';
1.356     tempelho 4996: 	   $savefolderpath = $env{'form.folderpath'};
1.548     raeburn  4997: 	   $env{'form.folderpath'}='default&'.&escape(&mt('Main Content'));
1.508     raeburn  4998:            $pathitem = '<input type="hidden" name="folderpath" value="'.
1.329     droeschl 4999: 	       &HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />';
                   5000:        }
                   5001:        my $postexec='';
                   5002:        if ($folder eq 'default') {
1.372     bisitz   5003:            $r->print('<script type="text/javascript">'."\n"
                   5004:                     .'// <![CDATA['."\n"
                   5005:                     .'this.window.name="loncapaclient";'."\n"
                   5006:                     .'// ]]>'."\n"
                   5007:                     .'</script>'."\n"
1.369     bisitz   5008:        );
1.329     droeschl 5009:        } else {
                   5010:            #$postexec='self.close();';
                   5011:        }
1.504     raeburn  5012:        my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_new.sequence';
                   5013:        my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_new.page';
1.329     droeschl 5014: 	my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
                   5015: 
                   5016: 	my $newnavform=(<<NNFORM);
                   5017: 	<form action="/adm/coursedocs" method="post" name="newnav">
1.570     raeburn  5018: 	<input type="hidden" name="active" value="ee" />
1.508     raeburn  5019: 	$pathitem
1.329     droeschl 5020: 	<input type="hidden" name="importdetail" 
                   5021: 	value="$lt{'navc'}=/adm/navmaps" />
1.423     onken    5022: 	<a class="LC_menubuttons_link" href="javascript:document.newnav.submit()">$lt{'navc'}</a>
1.329     droeschl 5023: 	$help{'Navigate_Content'}
                   5024: 	</form>
                   5025: NNFORM
                   5026: 	my $newsmppageform=(<<NSPFORM);
                   5027: 	<form action="/adm/coursedocs" method="post" name="newsmppg">
1.570     raeburn  5028: 	<input type="hidden" name="active" value="ee" />
1.508     raeburn  5029: 	$pathitem
1.329     droeschl 5030: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5031: 	<a class="LC_menubuttons_link" href="javascript:makesmppage();"> $lt{'sipa'}</a>
1.383     tempelho 5032: 	$help{'Simple Page'}
1.329     droeschl 5033: 	</form>
                   5034: NSPFORM
                   5035: 
                   5036: 	my $newsmpproblemform=(<<NSPROBFORM);
                   5037: 	<form action="/adm/coursedocs" method="post" name="newsmpproblem">
1.371     tempelho 5038: 	<input type="hidden" name="active" value="cc" />
1.508     raeburn  5039: 	$pathitem
1.329     droeschl 5040: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5041: 	<a class="LC_menubuttons_link" href="javascript:makesmpproblem();">$lt{'sipr'}</a>
1.572     raeburn  5042: 	$help{'Simple_Problem'}
1.329     droeschl 5043: 	</form>
                   5044: 
                   5045: NSPROBFORM
                   5046: 
                   5047: 	my $newdropboxform=(<<NDBFORM);
                   5048: 	<form action="/adm/coursedocs" method="post" name="newdropbox">
1.371     tempelho 5049: 	<input type="hidden" name="active" value="cc" />
1.508     raeburn  5050: 	$pathitem
1.329     droeschl 5051: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5052: 	<a class="LC_menubuttons_link" href="javascript:makedropbox();">$lt{'drbx'}</a>
1.554     raeburn  5053:         $help{'Dropbox'}
1.344     bisitz   5054: 	</form>
1.329     droeschl 5055: NDBFORM
                   5056: 
                   5057: 	my $newexuploadform=(<<NEXUFORM);
                   5058: 	<form action="/adm/coursedocs" method="post" name="newexamupload">
1.371     tempelho 5059: 	<input type="hidden" name="active" value="cc" />
1.508     raeburn  5060: 	$pathitem
1.329     droeschl 5061: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5062: 	<a class="LC_menubuttons_link" href="javascript:makeexamupload();">$lt{'scuf'}</a>
1.329     droeschl 5063: 	$help{'Score_Upload_Form'}
                   5064: 	</form>
                   5065: NEXUFORM
                   5066: 
                   5067: 	my $newbulform=(<<NBFORM);
                   5068: 	<form action="/adm/coursedocs" method="post" name="newbul">
1.570     raeburn  5069: 	<input type="hidden" name="active" value="dd" />
1.508     raeburn  5070: 	$pathitem
1.329     droeschl 5071: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5072: 	<a class="LC_menubuttons_link" href="javascript:makebulboard();" >$lt{'bull'}</a>
1.329     droeschl 5073: 	$help{'Bulletin Board'}
                   5074: 	</form>
                   5075: NBFORM
                   5076: 
                   5077: 	my $newaboutmeform=(<<NAMFORM);
                   5078: 	<form action="/adm/coursedocs" method="post" name="newaboutme">
1.570     raeburn  5079: 	<input type="hidden" name="active" value="dd" />
1.508     raeburn  5080: 	$pathitem
1.329     droeschl 5081: 	<input type="hidden" name="importdetail" 
                   5082: 	value="$plainname=/adm/$udom/$uname/aboutme" />
1.423     onken    5083: 	<a class="LC_menubuttons_link" href="javascript:document.newaboutme.submit()">$lt{'mypi'}</a>
1.347     weissno  5084: 	$help{'My Personal Information Page'}
1.329     droeschl 5085: 	</form>
                   5086: NAMFORM
                   5087: 
                   5088: 	my $newaboutsomeoneform=(<<NASOFORM);
                   5089: 	<form action="/adm/coursedocs" method="post" name="newaboutsomeone">
1.570     raeburn  5090: 	<input type="hidden" name="active" value="dd" />
1.508     raeburn  5091: 	$pathitem
1.329     droeschl 5092: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5093: 	<a class="LC_menubuttons_link" href="javascript:makeabout();">$lt{'abou'}</a>
1.329     droeschl 5094: 	</form>
                   5095: NASOFORM
                   5096: 
                   5097: 	my $newrosterform=(<<NROSTFORM);
                   5098: 	<form action="/adm/coursedocs" method="post" name="newroster">
1.570     raeburn  5099: 	<input type="hidden" name="active" value="dd" />
1.508     raeburn  5100: 	$pathitem
1.329     droeschl 5101: 	<input type="hidden" name="importdetail" 
                   5102: 	value="$lt{'rost'}=/adm/viewclasslist" />
1.423     onken    5103: 	<a class="LC_menubuttons_link" href="javascript:document.newroster.submit()">$lt{'rost'}</a>
1.556     raeburn  5104: 	$help{'Course_Roster'}
1.329     droeschl 5105: 	</form>
                   5106: NROSTFORM
                   5107: 
1.534     raeburn  5108:         my $newwebpage;
                   5109:         if ($folder =~ /^default_?(\d*)$/) {
                   5110:             $newwebpage = "/uploaded/$coursedom/$coursenum/docs/";
                   5111:             if ($1) {
                   5112:                 $newwebpage .= $1;
                   5113:             } else {
                   5114:                 $newwebpage .= 'default';
                   5115:             }
                   5116:             $newwebpage .= '/new.html';
                   5117:         }
                   5118:         my $newwebpageform =(<<NWEBFORM);
                   5119:         <form action="/adm/coursedocs" method="post" name="newwebpage">
1.570     raeburn  5120:         <input type="hidden" name="active" value="ee" />
1.534     raeburn  5121:         $pathitem
                   5122:         <input type="hidden" name="importdetail" value="$newwebpage" />
                   5123:         <a class="LC_menubuttons_link" href="javascript:makewebpage();">$lt{'webp'}</a>
1.556     raeburn  5124:         $help{'Web_Page'}
1.534     raeburn  5125:         </form>
                   5126: NWEBFORM
                   5127:  
                   5128: 
1.342     ehlerst  5129: my $specialdocumentsform;
1.383     tempelho 5130: my @specialdocumentsforma;
1.451     www      5131: my $gradingform;
                   5132: my @gradingforma;
                   5133: my $communityform;
                   5134: my @communityforma;
1.351     ehlerst  5135: my $newfolderform;
1.390     tempelho 5136: my $newfolderb;
1.342     ehlerst  5137: 
1.451     www      5138: 	my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.383     tempelho 5139: 	
1.329     droeschl 5140: 	my $newpageform=(<<NPFORM);
                   5141: 	<form action="/adm/coursedocs" method="post" name="newpage">
                   5142: 	<input type="hidden" name="folderpath" value="$path" />
                   5143: 	<input type="hidden" name="importdetail" value="" />
1.570     raeburn  5144: 	<input type="hidden" name="active" value="ee" />
1.423     onken    5145: 	<a class="LC_menubuttons_link" href="javascript:makenewpage(document.newpage,'$pageseq');">$lt{'newp'}</a>
1.383     tempelho 5146: 	$help{'Adding_Pages'}
1.329     droeschl 5147: 	</form>
                   5148: NPFORM
1.390     tempelho 5149: 
                   5150: 
1.351     ehlerst  5151: 	$newfolderform=(<<NFFORM);
1.329     droeschl 5152: 	<form action="/adm/coursedocs" method="post" name="newfolder">
1.508     raeburn  5153: 	$pathitem
1.329     droeschl 5154: 	<input type="hidden" name="importdetail" value="" />
1.570     raeburn  5155: 	<input type="hidden" name="active" value="" />
1.422     onken    5156: 	<a href="javascript:makenewfolder(document.newfolder,'$folderseq');">$lt{'newf'}</a>$help{'Adding_Folders'}
1.329     droeschl 5157: 	</form>
                   5158: NFFORM
                   5159: 
                   5160: 	my $newsylform=(<<NSYLFORM);
                   5161: 	<form action="/adm/coursedocs" method="post" name="newsyl">
1.570     raeburn  5162: 	<input type="hidden" name="active" value="ee" />
1.508     raeburn  5163: 	$pathitem
1.329     droeschl 5164: 	<input type="hidden" name="importdetail" 
                   5165: 	value="$lt{'syll'}=/public/$coursedom/$coursenum/syllabus" />
1.423     onken    5166: 	<a class="LC_menubuttons_link" href="javascript:document.newsyl.submit()">$lt{'syll'}</a>
1.329     droeschl 5167: 	$help{'Syllabus'}
1.383     tempelho 5168: 
1.329     droeschl 5169: 	</form>
                   5170: NSYLFORM
1.364     bisitz   5171: 
1.329     droeschl 5172: 	my $newgroupfileform=(<<NGFFORM);
                   5173: 	<form action="/adm/coursedocs" method="post" name="newgroupfiles">
1.570     raeburn  5174: 	<input type="hidden" name="active" value="dd" />
1.508     raeburn  5175: 	$pathitem
1.329     droeschl 5176: 	<input type="hidden" name="importdetail"
                   5177: 	value="$lt{'grpo'}=/adm/$coursedom/$coursenum/aboutme" />
1.423     onken    5178: 	<a class="LC_menubuttons_link" href="javascript:document.newgroupfiles.submit()">$lt{'grpo'}</a>
1.353     weissno  5179: 	$help{'Group Portfolio'}
1.329     droeschl 5180: 	</form>
                   5181: NGFFORM
1.383     tempelho 5182: 	@specialdocumentsforma=(
1.421     onken    5183: 	{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/page.png" alt="'.$lt{newp}.'"  onclick="javascript:makenewpage(document.newpage,\''.$pageseq.'\');" />'=>$newpageform},
1.417     droeschl 5184: 	{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/syllabus.png" alt="'.$lt{syll}.'" onclick="document.newsyl.submit()" />'=>$newsylform},
1.451     www      5185: 	{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/navigation.png" alt="'.$lt{navc}.'" onclick="document.newnav.submit()" />'=>$newnavform},
                   5186:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/simple.png" alt="'.$lt{sipa}.'" onclick="javascript:makesmppage();" />'=>$newsmppageform},
1.534     raeburn  5187:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/webpage.png" alt="'.$lt{webp}.'" onclick="javascript:makewebpage();" />'=>$newwebpageform},
1.451     www      5188:         );
                   5189:         $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma));
                   5190: 
1.434     raeburn  5191: 
                   5192:         my @importdoc = (
1.519     raeburn  5193:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="toggleUpload(\'ext\');" />'=>$extresourcesform}
                   5194:         );
                   5195:         unless ($container eq 'page') {
                   5196:             push(@importdoc,
                   5197:                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/ims.png" alt="'.$lt{imsf}.'" onclick="javascript:toggleUpload(\'ims\');" />'=>$imspform}
                   5198:             );
                   5199:         }
                   5200:         push(@importdoc,
1.558     raeburn  5201:             {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'doc\');" />'=>$fileuploadform}
1.519     raeburn  5202:         );
1.501     raeburn  5203:         $fileuploadform =  &create_form_ul(&create_list_elements(@importdoc));
1.434     raeburn  5204: 
1.451     www      5205:         @gradingforma=(
                   5206:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/simpprob.png" alt="'.$lt{sipr}.'" onclick="javascript:makesmpproblem();" />'=>$newsmpproblemform},
                   5207:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/dropbox.png" alt="'.$lt{drbx}.'" onclick="javascript:makedropbox();" />'=>$newdropboxform},
                   5208:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/scoreupfrm.png" alt="'.$lt{scuf}.'" onclick="javascript:makeexamupload();" />'=>$newexuploadform},
                   5209: 
                   5210:         );
                   5211:         $gradingform = &create_form_ul(&create_list_elements(@gradingforma));
                   5212: 
                   5213:         @communityforma=(
                   5214:        {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/bchat.png" alt="'.$lt{bull}.'" onclick="javascript:makebulboard();" />'=>$newbulform},
                   5215:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/myaboutme.png" alt="'.$lt{mypi}.'" onclick="javascript:makebulboard();" />'=>$newaboutmeform},
                   5216:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/aboutme.png" alt="'.$lt{abou}.'" onclick="javascript:makeabout();" />'=>$newaboutsomeoneform},
                   5217:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/clst.png" alt="'.$lt{rost}.'" onclick="document.newroster.submit()" />'=>$newrosterform},
                   5218:         {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/groupportfolio.png" alt="'.$lt{grpo}.'" onclick="document.newgroupfiles.submit()" />'=>$newgroupfileform},
                   5219:         );
                   5220:         $communityform = &create_form_ul(&create_list_elements(@communityforma));
1.383     tempelho 5221: 
1.330     tempelho 5222: my %orderhash = (
1.553     raeburn  5223:                 'aa' => ['Upload',$fileuploadform],
                   5224:                 'bb' => ['Import',$importpubform],
                   5225:                 'cc' => ['Grading',$gradingform],
1.330     tempelho 5226:                 );
1.519     raeburn  5227: unless ($container eq 'page') {
1.434     raeburn  5228:     $orderhash{'00'} = ['Newfolder',$newfolderform];
1.484     raeburn  5229:     $orderhash{'dd'} = ['Collaboration',$communityform];
1.553     raeburn  5230:     $orderhash{'ee'} = ['Other',$specialdocumentsform];
1.434     raeburn  5231: }
                   5232: 
1.341     ehlerst  5233:  $hadchanges=0;
1.484     raeburn  5234:        unless (($supplementalflag || $toolsflag)) {
1.458     raeburn  5235:           my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
1.508     raeburn  5236:                               $supplementalflag,\%orderhash,$iconpath,$pathitem);
1.443     www      5237:           if ($error) {
                   5238:              $r->print('<p><span class="LC_error">'.$error.'</span></p>');
                   5239:           }
                   5240:           if ($hadchanges) {
                   5241:              &mark_hash_old();
                   5242:           }
1.341     ehlerst  5243: 
1.443     www      5244:           &changewarning($r,'');
                   5245:         }
1.458     raeburn  5246:     }
1.442     www      5247: 
1.443     www      5248: # Supplemental documents start here
                   5249: 
1.329     droeschl 5250:        my $folder=$env{'form.folder'};
1.443     www      5251:        unless ($supplementalflag) {
1.329     droeschl 5252: 	   $folder='supplemental';
                   5253:        }
                   5254:        if ($folder =~ /^supplemental$/ &&
                   5255: 	   (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
1.446     www      5256:           $env{'form.folderpath'} = &supplemental_base();
1.393     raeburn  5257:        } elsif ($allowed) {
1.356     tempelho 5258: 	  $env{'form.folderpath'} = $savefolderpath;
1.329     droeschl 5259:        }
1.508     raeburn  5260:        $pathitem = '<input type="hidden" name="folderpath" value="'.
                   5261:                     &HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />';
1.329     droeschl 5262:        if ($allowed) {
                   5263: 	   my $folderseq=
1.504     raeburn  5264: 	       '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_new.sequence';
1.329     droeschl 5265: 
                   5266: 	my $supupdocform=(<<SUPDOCFORM);
1.501     raeburn  5267:         <a class="LC_menubuttons_link" href="javascript:toggleUpload('suppdoc');">
                   5268:         $lt{'upfi'}</a> $help{'Uploading_From_Harddrive'}
1.383     tempelho 5269: 	<form action="/adm/coursedocs" method="post" name="supuploaddocument" enctype="multipart/form-data">
1.516     raeburn  5270:         <fieldset id="uploadsuppdocform" style="display: none;">
1.501     raeburn  5271:         <legend>$lt{'upfi'}</legend>
1.371     tempelho 5272: 	<input type="hidden" name="active" value="ee" />	
1.329     droeschl 5273: 	$fileupload
                   5274: 	<br />
                   5275: 	<br />
                   5276: 	<span class="LC_nobreak">
                   5277: 	$checkbox
                   5278: 	</span>
                   5279: 	<br /><br />
                   5280: 	$lt{'comment'}:<br />
1.383     tempelho 5281: 	<textarea cols="50" rows="4" name="comment"></textarea>
1.329     droeschl 5282: 	<br />
1.508     raeburn  5283: 	$pathitem
1.329     droeschl 5284: 	<input type="hidden" name="cmd" value="upload_supplemental" />
1.501     raeburn  5285:         <input type='submit' value="$lt{'upld'}" />
                   5286:         </form>
1.329     droeschl 5287: SUPDOCFORM
                   5288: 
                   5289: 	my $supnewfolderform=(<<SNFFORM);
                   5290: 	<form action="/adm/coursedocs" method="post" name="supnewfolder">
1.570     raeburn  5291: 	<input type="hidden" name="active" value="" />
1.508     raeburn  5292:         $pathitem
1.329     droeschl 5293: 	<input type="hidden" name="importdetail" value="" />
1.423     onken    5294: 	<a class="LC_menubuttons_link" href="javascript:makenewfolder(document.supnewfolder,'$folderseq');">$lt{'newf'}</a> 
1.383     tempelho 5295: 	$help{'Adding_Folders'}
1.329     droeschl 5296: 	</form>
                   5297: SNFFORM
1.383     tempelho 5298: 	
1.510     raeburn  5299:         my $supextform =
                   5300:             &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem,
                   5301:                                                  $help{'Adding_External_Resource'});
1.329     droeschl 5302: 
                   5303: 	my $supnewsylform=(<<SNSFORM);
                   5304: 	<form action="/adm/coursedocs" method="post" name="supnewsyl">
1.371     tempelho 5305: 	<input type="hidden" name="active" value="ff" />
1.508     raeburn  5306:         $pathitem
1.329     droeschl 5307: 	<input type="hidden" name="importdetail" 
                   5308: 	value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.423     onken    5309: 	<a class="LC_menubuttons_link" href="javascript:document.supnewsyl.submit()">$lt{'syll'}</a>
1.329     droeschl 5310: 	$help{'Syllabus'}
                   5311: 	</form>
                   5312: SNSFORM
                   5313: 
                   5314: 	my $supnewaboutmeform=(<<SNAMFORM);
1.383     tempelho 5315: 	<form action="/adm/coursedocs" method="post" name="supnewaboutme">
1.371     tempelho 5316: 	<input type="hidden" name="active" value="ff" />
1.508     raeburn  5317:         $pathitem
1.329     droeschl 5318: 	<input type="hidden" name="importdetail" 
                   5319: 	value="$plainname=/adm/$udom/$uname/aboutme" />
1.423     onken    5320: 	<a class="LC_menubuttons_link" href="javascript:document.supnewaboutme.submit()">$lt{'mypi'}</a>
1.347     weissno  5321: 	$help{'My Personal Information Page'}
1.329     droeschl 5322: 	</form>
                   5323: SNAMFORM
                   5324: 
1.534     raeburn  5325:         my $supwebpage;
                   5326:         if ($folder =~ /^supplemental_?(\d*)$/) {
                   5327:             $supwebpage = "/uploaded/$coursedom/$coursenum/supplemental/";
                   5328:             if ($1) {
                   5329:                 $supwebpage .= $1;
                   5330:             } else {
                   5331:                 $supwebpage .= 'default';
                   5332:             }
                   5333:             $supwebpage .= '/new.html';
                   5334:         }
                   5335:         my $supwebpageform =(<<SWEBFORM);
                   5336:         <form action="/adm/coursedocs" method="post" name="supwebpage">
                   5337:         <input type="hidden" name="active" value="cc" />
                   5338:         $pathitem
                   5339:         <input type="hidden" name="importdetail" value="$supwebpage" />
                   5340:         <a class="LC_menubuttons_link" href="javascript:makewebpage('supp');">$lt{'webp'}</a>
1.556     raeburn  5341:         $help{'Web_Page'}
1.534     raeburn  5342:         </form>
                   5343: SWEBFORM
                   5344: 
1.333     muellerd 5345: 
1.383     tempelho 5346: my @specialdocs = (
1.417     droeschl 5347: 		{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/syllabus.png" alt="'.$lt{syll}.'" onclick="document.supnewsyl.submit()" />'
                   5348:             =>$supnewsylform},
                   5349: 		{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/myaboutme.png" alt="'.$lt{mypi}.'" onclick="document.supnewaboutme.submit()" />'
                   5350:             =>$supnewaboutmeform},
1.534     raeburn  5351:                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/webpage.png" alt="'.$lt{webp}.'" onclick="javascript:makewebpage('."'supp'".');" />'=>$supwebpageform},
                   5352: 
1.383     tempelho 5353: 		);
1.417     droeschl 5354: my @supimportdoc = (
1.515     raeburn  5355: 		{'<img class="LC_noBorder LC_middle" src="/res/adm/pages/extres.png" alt="'.$lt{extr}.'" onclick="javascript:toggleUpload(\'suppext\')" />'
1.501     raeburn  5356:             =>$supextform},
                   5357:                 {'<img class="LC_noBorder LC_middle" src="/res/adm/pages/pdfupload.png" alt="'.$lt{upl}.'" onclick="javascript:toggleUpload(\'suppdoc\');" />'
                   5358:             =>$supupdocform},
                   5359:                    );
                   5360: 
                   5361: $supupdocform =  &create_form_ul(&create_list_elements(@supimportdoc));
1.333     muellerd 5362: my %suporderhash = (
1.390     tempelho 5363: 		'00' => ['Supnewfolder', $supnewfolderform],
1.553     raeburn  5364:                 'ee' => ['Upload',$supupdocform],
                   5365:                 'ff' => ['Other',&create_form_ul(&create_list_elements(@specialdocs))]
1.333     muellerd 5366:                 );
1.443     www      5367:         if ($supplementalflag) {
1.458     raeburn  5368:            my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
1.508     raeburn  5369:                                $supplementalflag,\%suporderhash,$iconpath,$pathitem);
1.443     www      5370:            if ($error) {
                   5371:               $r->print('<p><span class="LC_error">'.$error.'</span></p>');
1.557     raeburn  5372:            } else {
                   5373:                if ($suppchanges) {
                   5374:                    my %servers = &Apache::lonnet::internet_dom_servers($coursedom);
                   5375:                    my @ids=&Apache::lonnet::current_machine_ids();
                   5376:                    foreach my $server (keys(%servers)) {
                   5377:                        next if (grep(/^\Q$server\E$/,@ids));
                   5378:                        my $hashid=$coursenum.':'.$coursedom;
1.566     raeburn  5379:                        my $cachekey = &escape('suppcount').':'.&escape($hashid);
                   5380:                        &Apache::lonnet::remote_devalidate_cache($server,[$cachekey]);
1.557     raeburn  5381:                    }
                   5382:                    &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
                   5383:                    undef($suppchanges);
                   5384:                }  
                   5385:            } 
1.393     raeburn  5386:         }
1.443     www      5387:     } elsif ($supplementalflag) {
1.458     raeburn  5388:         my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
1.508     raeburn  5389:                             $supplementalflag,'',$iconpath,$pathitem);
1.393     raeburn  5390:         if ($error) {
                   5391:             $r->print('<p><span class="LC_error">'.$error.'</span></p>');
1.383     tempelho 5392:         }
1.393     raeburn  5393:     }
1.389     tempelho 5394: 
1.510     raeburn  5395:     if ($needs_end) {
                   5396:         $r->print(&endContentScreen());
                   5397:     }
1.383     tempelho 5398: 
1.329     droeschl 5399:     if ($allowed) {
                   5400: 	$r->print('
                   5401: <form method="post" name="extimport" action="/adm/coursedocs">
                   5402:   <input type="hidden" name="title" />
                   5403:   <input type="hidden" name="url" />
                   5404:   <input type="hidden" name="useform" />
                   5405:   <input type="hidden" name="residx" />
                   5406: </form>');
                   5407:     }
1.484     raeburn  5408:   } elsif ($showdoc) {
1.329     droeschl 5409: # -------------------------------------------------------- This is showdoc mode
1.484     raeburn  5410:       $r->print("<h1>".&mt('Uploaded Document').' - '.
1.498     bisitz   5411: 		&Apache::lonnet::gettitle($r->uri).'</h1><p class="LC_warning">'.
1.329     droeschl 5412: &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><table>".
1.484     raeburn  5413:                 &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table>');
1.329     droeschl 5414:   }
                   5415:  }
                   5416:  $r->print(&Apache::loncommon::end_page());
                   5417:  return OK;
1.364     bisitz   5418: }
1.329     droeschl 5419: 
1.440     raeburn  5420: sub embedded_form_elems {
                   5421:     my ($phase,$primaryurl,$newidx) = @_;
                   5422:     my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   5423:     return <<STATE;
                   5424:     <input type="hidden" name="folderpath" value="$folderpath" />
                   5425:     <input type="hidden" name="cmd" value="upload_embedded" />
                   5426:     <input type="hidden" name="newidx" value="$newidx" />
                   5427:     <input type="hidden" name="phase" value="$phase" />
                   5428:     <input type="hidden" name="primaryurl" value="$primaryurl" />
                   5429: STATE
                   5430: }
                   5431: 
                   5432: sub embedded_destination {
                   5433:     my $folder=$env{'form.folder'};
                   5434:     my $destination = 'docs/';
                   5435:     if ($folder =~ /^supplemental/) {
                   5436:         $destination = 'supplemental/';
                   5437:     }
                   5438:     if (($folder eq 'default') || ($folder eq 'supplemental')) {
                   5439:         $destination .= 'default/';
                   5440:     } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
                   5441:         $destination .=  $2.'/';
                   5442:     }
                   5443:     $destination .= $env{'form.newidx'};
                   5444:     my $dir_root = '/userfiles';
                   5445:     return ($destination,$dir_root);
                   5446: }
                   5447: 
                   5448: sub return_to_editor {
                   5449:     my $actionurl = '/adm/coursedocs';
                   5450:     return '<p><form name="backtoeditor" method="post" action="'.$actionurl.'" />'."\n". 
                   5451:            '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" /></form>'."\n".
                   5452:            '<a href="javascript:document.backtoeditor.submit();">'.&mt('Return to Editor').
                   5453:            '</a></p>';
                   5454: }
                   5455: 
1.476     raeburn  5456: sub decompression_info {
                   5457:     my ($destination,$dir_root) = &embedded_destination();
                   5458:     my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
                   5459:     my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
                   5460:     my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
                   5461:     my $container='sequence';
1.480     raeburn  5462:     my ($pathitem,$hiddenelem);
1.583     raeburn  5463:     my @hiddens = ('newidx','comment','position','folderpath','archiveurl');
1.519     raeburn  5464:     if ($env{'form.folderpath'} =~ /\:1$/) {
1.476     raeburn  5465:         $container='page';
                   5466:     }
1.480     raeburn  5467:     unshift(@hiddens,$pathitem);
                   5468:     foreach my $item (@hiddens) {
                   5469:         if ($env{'form.'.$item}) {
                   5470:             $hiddenelem .= '<input type="hidden" name="'.$item.'" value="'.
1.583     raeburn  5471:                            &HTML::Entities::encode($env{'form.'.$item},'<>&"').'" />'."\n";
1.480     raeburn  5472:         }
1.477     raeburn  5473:     }
1.476     raeburn  5474:     return ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,
                   5475:             $hiddenelem);
                   5476: }
                   5477: 
                   5478: sub decompression_phase_one {
                   5479:     my ($dir,$file,$warning,$error,$output);
                   5480:     my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
                   5481:         &decompression_info();
1.490     raeburn  5482:     if ($env{'form.archiveurl'} !~ m{^/uploaded/\Q$docudom/$docuname/\E(?:docs|supplemental)/(?:default|\d+).*/([^/]+)$}) {
1.476     raeburn  5483:         $error = &mt('Archive file "[_1]" not in the expected location.',$env{'form.archiveurl'});
                   5484:     } else {
                   5485:         my $file = $1;
1.481     raeburn  5486:         $output = 
                   5487:             &Apache::loncommon::process_decompression($docudom,$docuname,$file,
                   5488:                                                       $destination,$dir_root,
                   5489:                                                       $hiddenelem);
                   5490:         if ($env{'form.autoextract_camtasia'}) {
                   5491:             $output .= &remove_archive($docudom,$docuname,$container);
                   5492:         }
1.476     raeburn  5493:     }
                   5494:     if ($error) {
                   5495:         $output .= '<p class="LC_error">'.&mt('Not extracted.').'<br />'.
                   5496:                    $error.'</p>'."\n";
                   5497:     }
                   5498:     if ($warning) {
                   5499:         $output .= '<p class="LC_warning">'.$warning.'</p>'."\n";
                   5500:     }
                   5501:     return $output;
                   5502: }
                   5503: 
                   5504: sub decompression_phase_two {
                   5505:     my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
                   5506:         &decompression_info();
1.481     raeburn  5507:     my $output;
1.480     raeburn  5508:     if ($env{'form.archivedelete'}) {
1.481     raeburn  5509:         $output = &remove_archive($docudom,$docuname,$container);
1.480     raeburn  5510:     }
                   5511:     $output .= 
1.481     raeburn  5512:         &Apache::loncommon::process_extracted_files('coursedocs',$docudom,$docuname,
1.476     raeburn  5513:                                                     $destination,$dir_root,$hiddenelem);
                   5514:     return $output;
                   5515: }
                   5516: 
1.480     raeburn  5517: sub remove_archive {
                   5518:     my ($docudom,$docuname,$container) = @_;
                   5519:     my $map = $env{'form.folder'}.'.'.$container;
1.481     raeburn  5520:     my ($output,$delwarning,$delresult,$url);
1.480     raeburn  5521:     my ($errtext,$fatal) = &mapread($docuname,$docudom,$map);
                   5522:     if ($fatal) {
                   5523:         if ($container eq 'page') {
                   5524:             $delwarning = &mt('An error occurred retrieving the contents of the current page.');
                   5525:         } else {
                   5526:             $delwarning = &mt('An error occurred retrieving the contents of the current folder.');
                   5527:         }
1.583     raeburn  5528:         $delwarning .= ' '.&mt('As a result the archive file has not been removed.');
1.480     raeburn  5529:     } else {
                   5530:         my $currcmd = $env{'form.cmd'};
                   5531:         my $position = $env{'form.position'};
1.583     raeburn  5532:         my $archiveidx = $position;
1.563     raeburn  5533:         if ($position > 0) {
1.583     raeburn  5534:             if (($env{'form.autoextract_camtasia'}) && (scalar(@LONCAPA::map::order) == 2)) {
                   5535:                 $archiveidx = $position-1;
                   5536:             }
                   5537:             $env{'form.cmd'} = 'remove_'.$archiveidx;
1.584   ! raeburn  5538:             my ($title,$url,@rrest) =
1.583     raeburn  5539:                 split(/:/,$LONCAPA::map::resources[$LONCAPA::map::order[$archiveidx]]);
                   5540:             if ($url eq $env{'form.archiveurl'}) {
                   5541:                 if (&handle_edit_cmd($docuname,$docudom)) {
                   5542:                     ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1);
                   5543:                     if ($fatal) {
                   5544:                         if ($container eq 'page') {
                   5545:                             $delwarning = &mt('An error occurred updating the contents of the current page.');
                   5546:                         } else {
                   5547:                             $delwarning = &mt('An error occurred updating the contents of the current folder.');
                   5548:                         }
1.480     raeburn  5549:                     } else {
1.583     raeburn  5550:                         $delresult = &mt('Archive file removed.');
1.480     raeburn  5551:                     }
                   5552:                 }
1.583     raeburn  5553:             } else {
                   5554:                 $delwarning .=  &mt('Archive file had unexpected item number in folder.').
                   5555:                                 ' '.&mt('As a result the archive file has not been removed.');
1.480     raeburn  5556:             }
                   5557:         }
                   5558:         $env{'form.cmd'} = $currcmd;
                   5559:     }
                   5560:     if ($delwarning) {
                   5561:         $output = '<p class="LC_warning">'.
                   5562:                    $delwarning.
                   5563:                    '</p>';
                   5564:     }
                   5565:     if ($delresult) {
                   5566:         $output .= '<p class="LC_info">'.
                   5567:                    $delresult.
                   5568:                    '</p>';
                   5569:     }
1.481     raeburn  5570:     return $output;
1.480     raeburn  5571: }
                   5572: 
1.484     raeburn  5573: sub generate_admin_menu {
                   5574:     my ($crstype) = @_;
                   5575:     my $lc_crstype = lc($crstype);
                   5576:     my ($home,$other,%outhash)=&authorhosts();
1.562     bisitz   5577:     my %lt= ( # do not translate here
1.484     raeburn  5578:                                          'vc'   => 'Verify Content',
                   5579:                                          'cv'   => 'Check/Set Resource Versions',
                   5580:                                          'ls'   => 'List Resource Identifiers',
                   5581:                                          'imse' => 'Export contents to IMS Archive',
1.568     raeburn  5582:                                          'dcd'  => "Copy $crstype Content to Authoring Space",
1.562     bisitz   5583:             );
1.484     raeburn  5584:     my ($candump,$dumpurl);
                   5585:     if ($home + $other > 0) {
                   5586:         $candump = 'F';
                   5587:         if ($home) {
                   5588:             $dumpurl = "javascript:injectData(document.courseverify,'dummy','dumpcourse','$lt{'dcd'}')";
                   5589:         } else {
                   5590:             my @hosts;
                   5591:             foreach my $aurole (keys(%outhash)) {
                   5592:                 unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) {
                   5593:                     push(@hosts,$outhash{$aurole});
1.538     raeburn  5594:                 }
1.484     raeburn  5595:             }
                   5596:             if (@hosts == 1) {
                   5597:                 my $switchto = '/adm/switchserver?otherserver='.$hosts[0].
                   5598:                                '&amp;role='.
                   5599:                                &HTML::Entities::encode($env{'request.role'},'"<>&').'&amp;origurl='.
                   5600:                                &HTML::Entities::encode('/adm/coursedocs?dumpcourse=1','"<>&');
                   5601:                 $dumpurl = "javascript:dump_needs_switchserver('$switchto')";
                   5602:             } else {
                   5603:                 $dumpurl = "javascript:choose_switchserver_window()";
                   5604:             }
                   5605:         }
                   5606:     }
                   5607:     my @menu=
                   5608:         ({  categorytitle=>'Administration',
                   5609:             items =>[
                   5610:                 {   linktext   => $lt{'vc'},
                   5611:                     url        => "javascript:injectData(document.courseverify,'dummy','verify','$lt{'vc'}')",
                   5612:                     permission => 'F',
1.571     raeburn  5613:                     help       => 'Docs_Verify_Content',
1.484     raeburn  5614:                     icon       => 'verify.png',
                   5615:                     linktitle  => 'Verify contents can be retrieved/rendered',
                   5616:                 },
                   5617:                 {   linktext => $lt{'cv'},
                   5618:                     url => "javascript:injectData(document.courseverify,'dummy','versions','$lt{'cv'}')",
                   5619:                     permission => 'F',
1.571     raeburn  5620:                     help       => 'Docs_Check_Resource_Versions',
1.484     raeburn  5621:                     icon       => 'resversion.png',
                   5622:                     linktitle  => "View version information for resources in your $lc_crstype, and fix/unfix use of specific versions",
                   5623:                 },
                   5624:                 {   linktext   => $lt{'ls'},
                   5625:                     url        => "javascript:injectData(document.courseverify,'dummy','listsymbs','$lt{'ls'}')",
                   5626:                     permission => 'F',
                   5627:                     #help => '',
                   5628:                     icon       => 'symbs.png',
                   5629:                     linktitle  => "List the unique identifier used for each resource instance in your $lc_crstype"
                   5630:                 },
                   5631:                 ]
                   5632:         },
                   5633:         {   categorytitle=>'Export',
                   5634:             items =>[
                   5635:                 {   linktext   => $lt{'imse'},
                   5636:                     url => "javascript:injectData(document.courseverify,'dummy','exportcourse','$lt{'imse'}')",
                   5637:                     permission => 'F',
                   5638:                     help       => 'Docs_Export_Course_Docs',
                   5639:                     icon       => 'imsexport.png',
                   5640:                     linktitle  => $lt{'imse'},
                   5641:                 },
                   5642:                 {   linktext   => $lt{'dcd'},
                   5643:                     url        => $dumpurl,
                   5644:                     permission => $candump,
1.571     raeburn  5645:                     help       => 'Docs_Dump_Course_Docs',
1.484     raeburn  5646:                     icon       => 'dump.png',
                   5647:                     linktitle  => $lt{'dcd'},
                   5648:                 },
                   5649:                 ]
                   5650:         });
                   5651:     return '<form action="/adm/coursedocs" method="post" name="courseverify">'."\n".
                   5652:            '<input type="hidden" id="dummy" />'."\n".
                   5653:            &Apache::lonhtmlcommon::generate_menu(@menu)."\n".
                   5654:            '</form>';
1.329     droeschl 5655: }
                   5656: 
                   5657: sub generate_edit_table {
1.538     raeburn  5658:     my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile,
                   5659:         $need_save,$copyfolder) = @_;
1.406     raeburn  5660:     return unless(ref($orderhash_ref) eq 'HASH');
1.342     ehlerst  5661:     my %orderhash = %{$orderhash_ref};
1.344     bisitz   5662:     my $form;
1.371     tempelho 5663:     my $activetab;
                   5664:     my $active;
1.570     raeburn  5665:     if (($env{'form.active'} ne '') && ($env{'form.active'} ne '00')) {
1.371     tempelho 5666:         $activetab = $env{'form.active'};
                   5667:     }
1.472     raeburn  5668:     my $backicon = $iconpath.'clickhere.gif';
1.525     raeburn  5669:     my $backtext = &mt('Exit Editor');
1.458     raeburn  5670:     $form = '<div class="LC_Box" style="margin:0;">'.
1.488     raeburn  5671:             '<ul id="navigation'.$tid.'" class="LC_TabContent">'."\n".
                   5672:             '<li class="goback">'.
1.546     raeburn  5673:             '<a href="javascript:toContents('."'$jumpto'".');">'.
1.488     raeburn  5674:             '<img src="'.$backicon.'" class="LC_icon" style="border: none; vertical-align: top;"'.
                   5675:             '  alt="'.$backtext.'" />'.$backtext.'</a></li>'."\n".
                   5676:             '<li>'.
                   5677:             '<a href="javascript:groupopen('."'$readfile'".',1);">'.
                   5678:             &mt('Undo Delete').'</a></li>'."\n";
                   5679:     if ($env{'form.docslog'}) {
                   5680:         $form .= '<li class="active">';
                   5681:     } else {
                   5682:         $form .= '<li>';
                   5683:     }
                   5684:     $form .= '<a href="javascript:toggleHistoryDisp(1);">'.
                   5685:              &mt('History').'</a></li>'."\n";
                   5686:     if ($env{'form.docslog'}) {
                   5687:         $form .= '<li><a href="javascript:toggleHistoryDisp(0);">'.
                   5688:                  &mt('Edit').'</a></li>'."\n";
1.484     raeburn  5689:     }
1.458     raeburn  5690:     foreach my $name (reverse(sort(keys(%orderhash)))) {
1.390     tempelho 5691:         if($name ne '00'){
1.371     tempelho 5692:             if($activetab eq '' || $activetab ne $name){
                   5693:                $active = '';
                   5694:             }elsif($activetab eq $name){
                   5695:                $active = 'class="active"';
                   5696:             }
1.458     raeburn  5697:             $form .= '<li style="float:right" '.$active
1.484     raeburn  5698:                 .' onclick="javascript:showPage(this, \''.$name.$tid.'\', \'navigation'.$tid.'\',\'content'.$tid.'\');"><a href="javascript:;"><b>'.&mt(${$orderhash{$name}}[0]).'</b></a></li>'."\n";
1.390     tempelho 5699:         } else {
1.570     raeburn  5700: 	    $form .= '<li style="float:right">'.${$orderhash{$name}}[1].'</li>'."\n";
1.390     tempelho 5701: 
                   5702: 	}
1.329     droeschl 5703:     }
1.484     raeburn  5704:     $form .= '</ul>'."\n";
                   5705:     $form .= '<div id="content'.$tid.'" style="padding: 0 0; margin: 0 0; overflow: hidden; clear:right">'."\n";
1.458     raeburn  5706: 
                   5707:     if ($to_show ne '') {
1.538     raeburn  5708:         my $saveform;
                   5709:         if ($need_save) {
                   5710:             my $button = &mt('Make changes');
                   5711:             my $path;
                   5712:             if ($env{'form.folderpath'}) {
                   5713:                 $path =
                   5714:                     &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   5715:             }
                   5716:             $saveform = <<"END";
                   5717: <div id="multisave" style="display:none; clear:both;" >
                   5718: <form name="saveactions" method="post" action="/adm/coursedocs" onsubmit="return checkSubmits();">
                   5719: <input type="hidden" name="folderpath" value="$path" />
                   5720: <input type="hidden" name="symb" value="$env{'form.symb'}" />
                   5721: <input type="hidden" name="allhiddenresource" value="" />
                   5722: <input type="hidden" name="allencrypturl" value="" />
                   5723: <input type="hidden" name="allrandompick" value="" />
                   5724: <input type="hidden" name="allrandomorder" value="" />
                   5725: <input type="hidden" name="changeparms" value="" />
                   5726: <input type="hidden" name="multiremove" value="" />
                   5727: <input type="hidden" name="multicut" value="" />
                   5728: <input type="hidden" name="multicopy" value="" />
                   5729: <input type="hidden" name="multichange" value="" />
                   5730: <input type="hidden" name="copyfolder" value="$copyfolder" />
                   5731: <input type="submit" name="savemultiples" value="$button" />
                   5732: </form>
                   5733: </div>
                   5734: END
                   5735:         }
                   5736:         $form .= '<div style="padding:0;margin:0;float:left">'.$to_show.'</div>'.$saveform."\n";
1.458     raeburn  5737:     }
1.363     ehlerst  5738:     foreach my $field (keys(%orderhash)){
1.390     tempelho 5739: 	if($field ne '00'){
1.422     onken    5740:             if($activetab eq '' || $activetab ne $field){
1.458     raeburn  5741:                 $active = 'style="display: none;float:left"';
1.422     onken    5742:             }elsif($activetab eq $field){
1.458     raeburn  5743:                 $active = 'style="display:block;float:left"';
1.422     onken    5744:             }
                   5745:             $form .= '<div id="'.$field.$tid.'"'
                   5746:                     .' class="LC_ContentBox" '.$active.'>'.${$orderhash{$field}}[1]
1.484     raeburn  5747:                     .'</div>'."\n";
1.363     ehlerst  5748:         }
                   5749:     }
1.484     raeburn  5750:     unless ($env{'form.docslog'}) {
                   5751:         $form .= '</div></div>'."\n";
                   5752:     }
1.329     droeschl 5753:     return $form;
                   5754: }
                   5755: 
                   5756: sub editing_js {
1.472     raeburn  5757:     my ($udom,$uname,$supplementalflag) = @_;
1.329     droeschl 5758:     my %lt = &Apache::lonlocal::texthash(
                   5759:                                           p_mnf => 'Name of New Folder',
                   5760:                                           t_mnf => 'New Folder',
                   5761:                                           p_mnp => 'Name of New Page',
                   5762:                                           t_mnp => 'New Page',
1.451     www      5763:                                           p_mxu => 'Title for the External Score',
1.349     biermanm 5764:                                           p_msp => 'Name of Simple Course Page',
1.329     droeschl 5765:                                           p_msb => 'Title for the Problem',
                   5766:                                           p_mdb => 'Title for the Drop Box',
1.336     schafran 5767:                                           p_mbb => 'Title for the Discussion Board',
1.534     raeburn  5768:                                           p_mwp => 'Title for Web Page', 
1.348     weissno  5769:                                           p_mab => "Enter user:domain for User's Personal Information Page",
1.352     bisitz   5770:                                           p_mab2 => 'Personal Information Page of ',
1.329     droeschl 5771:                                           p_mab_alrt1 => 'Not a valid user:domain',
                   5772:                                           p_mab_alrt2 => 'Please enter both user and domain in the format user:domain',
                   5773:                                           p_chn => 'New Title',
                   5774:                                           p_rmr1 => 'WARNING: Removing a resource makes associated grades and scores inaccessible!',
                   5775:                                           p_rmr2a => 'Remove[_99]',
                   5776:                                           p_rmr2b => '?[_99]',
1.542     raeburn  5777:                                           p_rmr3a => 'Remove those [_2]',
                   5778:                                           p_rmr3b => 'items?[_2]',
1.329     droeschl 5779:                                           p_ctr1a => 'WARNING: Cutting a resource makes associated grades and scores inaccessible!',
                   5780:                                           p_ctr1b => 'Grades remain inaccessible if resource is pasted into another folder.',
                   5781:                                           p_ctr2a => 'Cut[_98]',
1.478     raeburn  5782:                                           p_ctr2b => '?[_98]',
1.542     raeburn  5783:                                           p_ctr3a => 'Cut those[_2]',
                   5784:                                           p_ctr3b => 'items?[_2]',
1.478     raeburn  5785:                                           rpck    => 'Enter number to pick (e.g., 3)',
1.501     raeburn  5786:                                           imsfile => 'You must choose an IMS package for import',
                   5787:                                           imscms  => 'You must select which Course Management System was the source of the IMS package',
                   5788:                                           invurl  => 'Invalid URL',
                   5789:                                           titbl   => 'Title is blank',
1.538     raeburn  5790:                                           more    => '(More ...)',
                   5791:                                           less    => '(Less ...)',
1.543     raeburn  5792:                                           noor    => 'No actions selected or changes to settings specified.',
                   5793:                                           noch    => 'No changes to settings specified.',
                   5794:                                           noac    => 'No actions selected.',
1.329     droeschl 5795:                                         );
                   5796: 
1.433     raeburn  5797:     my $crstype = &Apache::loncommon::course_type();
1.434     raeburn  5798:     my $docs_folderpath = &HTML::Entities::encode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'},'<>&"');
                   5799:     my $main_container_page;
1.519     raeburn  5800:     if (&HTML::Entities::decode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'}) =~ /\:1$/) {
                   5801:         $main_container_page = 1;
1.434     raeburn  5802:     }
1.538     raeburn  5803:     my $toplevelmain = 
1.548     raeburn  5804:         &escape(&mt('Main Content').':::::');
1.446     www      5805:     my $toplevelsupp = &supplemental_base();
1.433     raeburn  5806: 
1.525     raeburn  5807:     my $backtourl;
1.530     raeburn  5808:     if ($env{'docs.exit.'.$env{'request.course.id'}} =~ /^direct_(.+)$/) {
                   5809:         my $caller = $1;
1.525     raeburn  5810:         if ($caller =~ /^supplemental/) {
                   5811:             $backtourl = '/adm/supplemental?folderpath='.&escape($caller);
                   5812:         } else {
                   5813:             my ($map,$id,$res)=&Apache::lonnet::decode_symb($caller);
                   5814:             $res = &Apache::lonnet::clutter($res);
                   5815:             if (&Apache::lonnet::is_on_map($res)) {
                   5816:                 $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($res),'<>&"').'?symb='.
                   5817:                              &HTML::Entities::encode($caller,'<>&"');
1.544     raeburn  5818:             } else {
                   5819:                 $backtourl = '/adm/navmaps';
1.525     raeburn  5820:             }
                   5821:         }
                   5822:     } elsif ($env{'docs.exit.'.$env{'request.course.id'}} eq '/adm/menu') {
                   5823:         $backtourl = '/adm/menu';
                   5824:     } elsif ($supplementalflag) {
1.472     raeburn  5825:         $backtourl = '/adm/supplemental';
1.525     raeburn  5826:     } else {
                   5827:         $backtourl = '/adm/navmaps';
1.472     raeburn  5828:     }
                   5829: 
1.519     raeburn  5830:     my $fieldsets = "'ext','doc'";
                   5831:     unless ($main_container_page) {
                   5832:         $fieldsets .=",'ims'";
                   5833:     }
1.501     raeburn  5834:     if ($supplementalflag) {
                   5835:         $fieldsets = "'suppext','suppdoc'";
                   5836:     }
                   5837: 
1.329     droeschl 5838:     return <<ENDNEWSCRIPT;
                   5839: function makenewfolder(targetform,folderseq) {
                   5840:     var foldername=prompt('$lt{"p_mnf"}','$lt{"t_mnf"}');
                   5841:     if (foldername) {
                   5842:        targetform.importdetail.value=escape(foldername)+"="+folderseq;
                   5843:         targetform.submit();
                   5844:     }
                   5845: }
                   5846: 
                   5847: function makenewpage(targetform,folderseq) {
                   5848:     var pagename=prompt('$lt{"p_mnp"}','$lt{"t_mnp"}');
                   5849:     if (pagename) {
                   5850:         targetform.importdetail.value=escape(pagename)+"="+folderseq;
                   5851:         targetform.submit();
                   5852:     }
                   5853: }
                   5854: 
                   5855: function makeexamupload() {
                   5856:    var title=prompt('$lt{"p_mxu"}');
1.344     bisitz   5857:    if (title) {
1.329     droeschl 5858:     this.document.forms.newexamupload.importdetail.value=
                   5859: 	escape(title)+'=/res/lib/templates/examupload.problem';
                   5860:     this.document.forms.newexamupload.submit();
                   5861:    }
                   5862: }
                   5863: 
                   5864: function makesmppage() {
                   5865:    var title=prompt('$lt{"p_msp"}');
1.344     bisitz   5866:    if (title) {
1.329     droeschl 5867:     this.document.forms.newsmppg.importdetail.value=
1.533     raeburn  5868: 	escape(title)+'=/adm/$udom/$uname/new/smppg';
1.329     droeschl 5869:     this.document.forms.newsmppg.submit();
                   5870:    }
                   5871: }
                   5872: 
1.534     raeburn  5873: function makewebpage(type) {
                   5874:    var title=prompt('$lt{"p_mwp"}');
                   5875:    var formname;
                   5876:    if (type == 'supp') {
                   5877:        formname = this.document.forms.supwebpage;
                   5878:    } else {
                   5879:        formname = this.document.forms.newwebpage;
                   5880:    }
                   5881:    if (title) {
                   5882:        var webpage = formname.importdetail.value; 
                   5883:        formname.importdetail.value = escape(title)+'='+webpage;
                   5884:        formname.submit();
                   5885:    }
                   5886: }
                   5887: 
1.329     droeschl 5888: function makesmpproblem() {
                   5889:    var title=prompt('$lt{"p_msb"}');
1.344     bisitz   5890:    if (title) {
1.329     droeschl 5891:     this.document.forms.newsmpproblem.importdetail.value=
                   5892: 	escape(title)+'=/res/lib/templates/simpleproblem.problem';
                   5893:     this.document.forms.newsmpproblem.submit();
                   5894:    }
                   5895: }
                   5896: 
                   5897: function makedropbox() {
                   5898:    var title=prompt('$lt{"p_mdb"}');
1.344     bisitz   5899:    if (title) {
1.329     droeschl 5900:     this.document.forms.newdropbox.importdetail.value=
                   5901:         escape(title)+'=/res/lib/templates/DropBox.problem';
                   5902:     this.document.forms.newdropbox.submit();
                   5903:    }
                   5904: }
                   5905: 
                   5906: function makebulboard() {
                   5907:    var title=prompt('$lt{"p_mbb"}');
                   5908:    if (title) {
                   5909:     this.document.forms.newbul.importdetail.value=
1.533     raeburn  5910: 	escape(title)+'=/adm/$udom/$uname/new/bulletinboard';
1.329     droeschl 5911:     this.document.forms.newbul.submit();
                   5912:    }
                   5913: }
                   5914: 
                   5915: function makeabout() {
                   5916:    var user=prompt("$lt{'p_mab'}");
                   5917:    if (user) {
                   5918:        var comp=new Array();
                   5919:        comp=user.split(':');
                   5920:        if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) {
                   5921: 	   if ((comp[0]) && (comp[1])) {
                   5922: 	       this.document.forms.newaboutsomeone.importdetail.value=
                   5923: 		   '$lt{"p_mab2"}'+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme';
1.335     ehlerst  5924:        this.document.forms.newaboutsomeone.submit();
                   5925:    } else {
                   5926:        alert("$lt{'p_mab_alrt1'}");
1.329     droeschl 5927:    }
1.335     ehlerst  5928: } else {
                   5929:    alert("$lt{'p_mab_alrt2'}");
                   5930: }
                   5931: }
1.329     droeschl 5932: }
                   5933: 
1.501     raeburn  5934: function toggleUpload(caller) {
                   5935:     var blocks = Array($fieldsets);
                   5936:     for (var i=0; i<blocks.length; i++) {
                   5937:         var disp = 'none';
                   5938:         if (caller == blocks[i]) {
                   5939:             var curr = document.getElementById('upload'+caller+'form').style.display;
                   5940:             if (curr == 'none') {
                   5941:                 disp='block';
                   5942:             }
                   5943:         }
                   5944:         document.getElementById('upload'+blocks[i]+'form').style.display=disp;
                   5945:     }
1.502     raeburn  5946:     resize_scrollbox('contentscroll','1','1');
                   5947:     return;
                   5948: }
                   5949: 
1.514     raeburn  5950: function toggleMap(caller) {
1.502     raeburn  5951:     var disp = 'none';
1.510     raeburn  5952:     if (document.getElementById('importmapform')) {
1.514     raeburn  5953:         if (caller == 'map') {
                   5954:             var curr = document.getElementById('importmapform').style.display;
                   5955:             if (curr == 'none') {
                   5956:                 disp='block';
                   5957:             }
1.510     raeburn  5958:         }
                   5959:         document.getElementById('importmapform').style.display=disp;
                   5960:         resize_scrollbox('contentscroll','1','1');
1.502     raeburn  5961:     }
1.501     raeburn  5962:     return;
1.329     droeschl 5963: }
                   5964: 
1.501     raeburn  5965: function makeims(imsform) {
                   5966:     if ((imsform.uploaddoc.value == '')  || (!imsform.uploaddoc.value)) {
                   5967:         alert("$lt{'imsfile'}");
                   5968:         return;
                   5969:     }
                   5970:     if (imsform.source.selectedIndex == 0) {
                   5971:         alert("$lt{'imscms'}");
                   5972:         return;
                   5973:     }
                   5974:     newWindow = window.open('', 'IMSimport',"HEIGHT=700,WIDTH=750,scrollbars=yes");
                   5975:     imsform.submit();
                   5976: }
                   5977: 
1.519     raeburn  5978: function changename(folderpath,index,oldtitle) {
1.335     ehlerst  5979: var title=prompt('$lt{"p_chn"}',oldtitle);
                   5980: if (title) {
1.538     raeburn  5981: this.document.forms.renameform.markcopy.value='';
1.335     ehlerst  5982: this.document.forms.renameform.title.value=title;
                   5983: this.document.forms.renameform.cmd.value='rename_'+index;
1.519     raeburn  5984: this.document.forms.renameform.folderpath.value=folderpath;
1.335     ehlerst  5985: this.document.forms.renameform.submit();
                   5986: }
1.329     droeschl 5987: }
                   5988: 
1.478     raeburn  5989: function updatePick(targetform,index,caller) {
1.537     raeburn  5990:     var pickitem;
                   5991:     var picknumitem;
                   5992:     var picknumtext;
                   5993:     if (index == 'all') {
                   5994:         pickitem = document.getElementById('randompickall');
                   5995:         picknumitem = document.getElementById('rpicknumall');
                   5996:         picknumtext = document.getElementById('rpicktextall');
                   5997:     } else {
                   5998:         pickitem = document.getElementById('randompick_'+index);
                   5999:         picknumitem = document.getElementById('rpicknum_'+index);
                   6000:         picknumtext = document.getElementById('randompicknum_'+index);
                   6001:     }
1.478     raeburn  6002:     if (pickitem.checked) {
                   6003:         var picknum=prompt('$lt{"rpck"}',picknumitem.value);
                   6004:         if (picknum == '' || picknum == null) {
                   6005:             if (caller == 'check') {
                   6006:                 pickitem.checked=false;
1.537     raeburn  6007:                 if (index == 'all') {
                   6008:                     picknumtext.innerHTML = '';
                   6009:                     if (caller == 'link') {
                   6010:                         propagateState(targetform,'rpicknum');
                   6011:                     }
                   6012:                 } else {
1.538     raeburn  6013:                     checkForSubmit(targetform,'randompick','settings');
1.537     raeburn  6014:                 }
1.478     raeburn  6015:             }
                   6016:         } else {
                   6017:             picknum.toString();
                   6018:             var regexdigit=/^\\d+\$/;
                   6019:             if (regexdigit.test(picknum)) {
                   6020:                 picknumitem.value = picknum;
1.537     raeburn  6021:                 if (index == 'all') {
1.538     raeburn  6022:                     picknumtext.innerHTML = '&nbsp;<a href="javascript:updatePick(document.cumulativesettings,\\'all\\',\\'link\\');">'+picknum+'</a>';
1.537     raeburn  6023:                     if (caller == 'link') {
                   6024:                         propagateState(targetform,'rpicknum');
                   6025:                     }
                   6026:                 } else {
                   6027:                     picknumtext.innerHTML = '&nbsp;<a href="javascript:updatePick(document.edit_randompick_'+index+',\\''+index+'\\',\\'link\\');">'+picknum+'</a>';
1.538     raeburn  6028:                     checkForSubmit(targetform,'randompick','settings');
1.537     raeburn  6029:                 }
1.478     raeburn  6030:             } else {
                   6031:                 if (caller == 'check') {
1.537     raeburn  6032:                     if (index == 'all') {
                   6033:                         picknumtext.innerHTML = '';
                   6034:                         if (caller == 'link') {
                   6035:                             propagateState(targetform,'rpicknum');
                   6036:                         }
                   6037:                     } else {
                   6038:                         pickitem.checked=false;
1.538     raeburn  6039:                         checkForSubmit(targetform,'randompick','settings');
1.537     raeburn  6040:                     }
1.478     raeburn  6041:                 }
                   6042:                 return;
                   6043:             }
                   6044:         }
                   6045:     } else {
1.537     raeburn  6046:         picknumitem.value = '';
                   6047:         picknumtext.innerHTML = '';
                   6048:         if (index == 'all') {
                   6049:             if (caller == 'link') {
                   6050:                 propagateState(targetform,'rpicknum');
                   6051:             }
                   6052:         } else {
1.538     raeburn  6053:             checkForSubmit(targetform,'randompick','settings');
1.537     raeburn  6054:         }
                   6055:     }
                   6056: }
                   6057: 
                   6058: function propagateState(form,param) {
                   6059:     if (document.getElementById(param+'all')) {
                   6060:         var setcheck = 0;
                   6061:         var rpick = 0;
                   6062:         if (param == 'rpicknum') {
                   6063:             if (document.getElementById('randompickall')) {
                   6064:                 if (document.getElementById('randompickall').checked) {
                   6065:                     if (document.getElementById('rpicknumall')) {
                   6066:                         rpick = document.getElementById('rpicknumall').value;
                   6067:                     }
                   6068:                 }
                   6069:             }
                   6070:         } else {
                   6071:             if (document.getElementById(param+'all').checked) {
                   6072:                 setcheck = 1;
                   6073:             }
                   6074:         }
1.538     raeburn  6075:         var allidxlist;
                   6076:         if ((param == 'remove') || (param == 'cut') || (param == 'copy')) {
                   6077:             if (document.getElementById('all'+param+'idx')) {
                   6078:                 allidxlist = document.getElementById('all'+param+'idx').value;
                   6079:             }
                   6080:             var actions = new Array ('remove','cut','copy');
                   6081:             for (var i=0; i<actions.length; i++) {
                   6082:                 if (actions[i] != param) {
                   6083:                     if (document.getElementById(actions[i]+'all')) {
                   6084:                         document.getElementById(actions[i]+'all').checked = false; 
                   6085:                     }
                   6086:                 }
                   6087:             }
                   6088:         }
1.537     raeburn  6089:         if ((param == 'encrypturl') || (param == 'hiddenresource')) {
1.538     raeburn  6090:             allidxlist = form.allidx.value;
                   6091:         }
                   6092:         if ((param == 'randompick') || (param == 'rpicknum') || (param == 'randomorder')) {
                   6093:             allidxlist = form.allmapidx.value;
                   6094:         }
                   6095:         if ((allidxlist != '') && (allidxlist != null)) {
                   6096:             var allidxs = allidxlist.split(',');
                   6097:             if (allidxs.length > 1) {
                   6098:                 for (var i=0; i<allidxs.length; i++) {
                   6099:                     if (document.getElementById(param+'_'+allidxs[i])) {
                   6100:                         if (param == 'rpicknum') {
                   6101:                             if (document.getElementById('randompick_'+allidxs[i])) {
                   6102:                                 if (document.getElementById('randompick_'+allidxs[i]).checked) {
                   6103:                                     document.getElementById(param+'_'+allidxs[i]).value = rpick;
                   6104:                                     if (rpick > 0) {
                   6105:                                         document.getElementById('randompicknum_'+allidxs[i]).innerHTML = ':&nbsp;<a href="javascript:updatePick(document.edit_randompick_'+allidxs[i]+',\\''+allidxs[i]+'\\',\\'link\\')">'+rpick+'</a>';
                   6106:                                     } else {
                   6107:                                         document.getElementById('randompicknum_'+allidxs[i]).innerHTML =  '';
                   6108:                                     }
                   6109:                                 }
                   6110:                             }
                   6111:                         } else {
1.537     raeburn  6112:                             if (setcheck == 1) {
                   6113:                                 document.getElementById(param+'_'+allidxs[i]).checked = true;
                   6114:                             } else {
                   6115:                                 document.getElementById(param+'_'+allidxs[i]).checked = false;
1.538     raeburn  6116:                                 if (param == 'randompick') {
                   6117:                                     document.getElementById('randompicknum_'+allidxs[i]).innerHTML =  '';
                   6118:                                 }
1.537     raeburn  6119:                             }
                   6120:                         }
                   6121:                     }
                   6122:                 }
1.538     raeburn  6123:                 if (setcheck == 1) {
                   6124:                     if ((param == 'remove') || (param == 'cut') || (param == 'copy')) {
                   6125:                         var actions = new Array('copy','cut','remove');
                   6126:                         for (var i=0; i<actions.length; i++) {
                   6127:                             var otheractions;
                   6128:                             var otheridxs;
                   6129:                             if (actions[i] === param) {
                   6130:                                 continue;
                   6131:                             } else {
                   6132:                                 if (document.getElementById('all'+actions[i]+'idx')) {
                   6133:                                     otheractions = document.getElementById('all'+actions[i]+'idx').value;
                   6134:                                     otheridxs = otheractions.split(',');
                   6135:                                     if (otheridxs.length > 1) {
                   6136:                                         for (var j=0; j<otheridxs.length; j++) {
                   6137:                                             if (document.getElementById(actions[i]+'_'+otheridxs[j])) {
                   6138:                                                 document.getElementById(actions[i]+'_'+otheridxs[j]).checked = false;
                   6139:                                             }
1.537     raeburn  6140:                                         }
                   6141:                                     }
                   6142:                                 }
1.538     raeburn  6143:                             }
                   6144:                         } 
                   6145:                     }
                   6146:                 }
                   6147:             }
                   6148:         }
                   6149:     }
                   6150:     return;
                   6151: }
                   6152: 
                   6153: function checkForSubmit(targetform,param,context,idx,folderpath,index,oldtitle,skip_confirm,container,folder) {
1.539     raeburn  6154:     var dosettings;
                   6155:     var doaction;
1.538     raeburn  6156:     var control = document.togglemultsettings;
                   6157:     if (context == 'actions') {
                   6158:         control = document.togglemultactions;
1.539     raeburn  6159:         doaction = 1; 
                   6160:     } else {
                   6161:         dosettings = 1;
1.538     raeburn  6162:     }
1.539     raeburn  6163:     if (control) {
                   6164:         if (control.showmultpick.length) {
                   6165:             for (var i=0; i<control.showmultpick.length; i++) {
                   6166:                 if (control.showmultpick[i].checked) {
                   6167:                     if (control.showmultpick[i].value == 1) {
                   6168:                         if (context == 'settings') {
                   6169:                             dosettings = 0;
                   6170:                         } else {
                   6171:                             doaction = 0;
1.538     raeburn  6172:                         }
                   6173:                     }
                   6174:                 }
1.537     raeburn  6175:             }
                   6176:         }
1.539     raeburn  6177:     }
                   6178:     if (context == 'settings') {
                   6179:         if (dosettings == 1) {
1.538     raeburn  6180:             targetform.changeparms.value=param;
                   6181:             targetform.submit();
                   6182:         }
1.537     raeburn  6183:     }
1.539     raeburn  6184:     if (context == 'actions') {
                   6185:         if (doaction == 1) {
                   6186:             targetform.cmd.value=param+'_'+index;
                   6187:             targetform.folderpath.value=folderpath;
                   6188:             targetform.markcopy.value=idx+':'+param;
                   6189:             targetform.copyfolder.value=folder+'.'+container;
                   6190:             if (param == 'remove') {
                   6191:                 if (skip_confirm || confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr2a"} "'+oldtitle+'" $lt{"p_rmr2b"}')) {
                   6192:                     targetform.markcopy.value='';
                   6193:                     targetform.copyfolder.value='';
                   6194:                     targetform.submit();
                   6195:                 }
                   6196:             }
                   6197:             if (param == 'cut') {
                   6198:                 if (skip_confirm || confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr2a"} "'+oldtitle+'" $lt{"p_ctr2b"}')) {
                   6199:                     targetform.submit();
                   6200:                     return;
                   6201:                 }
                   6202:             }
                   6203:             if (param == 'copy') {
                   6204:                 targetform.submit();
                   6205:                 return;
                   6206:             }
                   6207:             targetform.markcopy.value='';
                   6208:             targetform.copyfolder.value='';
                   6209:             targetform.cmd.value='';
                   6210:             targetform.folderpath.value='';
                   6211:             return;
                   6212:         } else {
                   6213:             if (document.getElementById(param+'_'+idx)) {
                   6214:                 item = document.getElementById(param+'_'+idx);
                   6215:                 if (item.type == 'checkbox') {
                   6216:                     if (item.checked) {
                   6217:                         item.checked = false;
                   6218:                     } else {
                   6219:                         item.checked = true;
                   6220:                         singleCheck(item,idx,param);
                   6221:                     }
                   6222:                 }
                   6223:             }
                   6224:         }
                   6225:     }
1.537     raeburn  6226:     return;
                   6227: }
                   6228: 
1.538     raeburn  6229: function singleCheck(caller,idx,action) {
                   6230:     actions = new Array('cut','copy','remove');
                   6231:     if (caller.checked) {
                   6232:         for (var i=0; i<actions.length; i++) {
                   6233:             if (actions[i] != action) {
                   6234:                 if (document.getElementById(actions[i]+'_'+idx)) {
                   6235:                     if (document.getElementById(actions[i]+'_'+idx).checked) {
                   6236:                         document.getElementById(actions[i]+'_'+idx).checked = false;
                   6237:                     }
1.537     raeburn  6238:                 }
                   6239:             }
                   6240:         }
1.478     raeburn  6241:     }
1.537     raeburn  6242:     return;
1.478     raeburn  6243: }
                   6244: 
1.334     muellerd 6245: function unselectInactive(nav) {
1.335     ehlerst  6246: currentNav = document.getElementById(nav);
                   6247: currentLis = currentNav.getElementsByTagName('LI');
                   6248: for (i = 0; i < currentLis.length; i++) {
1.472     raeburn  6249:         if (currentLis[i].className == 'goback') {
                   6250:             currentLis[i].className = 'goback';
                   6251:         } else {
                   6252: 	    if (currentLis[i].className == 'right active' || currentLis[i].className == 'right') {
1.374     tempelho 6253: 		currentLis[i].className = 'right';
1.472     raeburn  6254: 	    } else {
1.374     tempelho 6255: 		currentLis[i].className = 'i';
1.472     raeburn  6256: 	    }
                   6257:         }
1.335     ehlerst  6258: }
1.332     tempelho 6259: }
                   6260: 
1.334     muellerd 6261: function hideAll(current, nav, data) {
1.335     ehlerst  6262: unselectInactive(nav);
1.570     raeburn  6263: if (current) { 
                   6264:     if (current.className == 'right'){
                   6265:         current.className = 'right active'
                   6266:     } else {
                   6267:         current.className = 'active';
                   6268:     }
1.374     tempelho 6269: }
1.335     ehlerst  6270: currentData = document.getElementById(data);
                   6271: currentDivs = currentData.getElementsByTagName('DIV');
                   6272: for (i = 0; i < currentDivs.length; i++) {
                   6273: 	if(currentDivs[i].className == 'LC_ContentBox'){
1.333     muellerd 6274: 		currentDivs[i].style.display = 'none';
1.330     tempelho 6275: 	}
                   6276: }
1.335     ehlerst  6277: }
1.330     tempelho 6278: 
1.374     tempelho 6279: function openTabs(pageId) {
                   6280: 	tabnav = document.getElementById(pageId).getElementsByTagName('UL');	
1.383     tempelho 6281: 	if(tabnav.length > 2 ){
1.389     tempelho 6282: 		currentNav = document.getElementById(tabnav[1].id);
1.374     tempelho 6283: 		currentLis = currentNav.getElementsByTagName('LI');
                   6284: 		for(i = 0; i< currentLis.length; i++){
                   6285: 			if(currentLis[i].className == 'active') {
1.375     tempelho 6286: 				funcString = currentLis[i].onclick.toString();
                   6287: 				tab = funcString.split('"');
1.420     onken    6288:                                 if(tab.length < 2) {
                   6289:                                    tab = funcString.split("'");
                   6290:                                 }
1.375     tempelho 6291: 				currentData = document.getElementById(tab[1]);
                   6292:         			currentData.style.display = 'block';
1.374     tempelho 6293: 			}	
                   6294: 		}
                   6295: 	}
                   6296: }
                   6297: 
1.334     muellerd 6298: function showPage(current, pageId, nav, data) {
1.570     raeburn  6299:         currstate = current.className;
1.334     muellerd 6300: 	hideAll(current, nav, data);
1.375     tempelho 6301: 	openTabs(pageId);
1.334     muellerd 6302: 	unselectInactive(nav);
1.570     raeburn  6303:         if ((currstate == 'active') || (currstate == 'right active')) {
                   6304:             if (currstate == 'active') {
                   6305: 	        current.className = '';
                   6306:             } else {
                   6307:                 current.className = 'right';
                   6308:             }
                   6309:             activeTab = ''; 
                   6310:             toggleUpload();
                   6311:             toggleMap();
                   6312:             resize_scrollbox('contentscroll','1','0');
                   6313:             return;
                   6314:         } else {
                   6315:             current.className = 'active';
                   6316:         }
1.330     tempelho 6317: 	currentData = document.getElementById(pageId);
                   6318: 	currentData.style.display = 'block';
1.458     raeburn  6319:         activeTab = pageId;
1.501     raeburn  6320:         toggleUpload();
1.503     raeburn  6321:         toggleMap();
1.433     raeburn  6322:         if (nav == 'mainnav') {
                   6323:             var storedpath = "$docs_folderpath";
1.434     raeburn  6324:             var storedpage = "$main_container_page";
1.433     raeburn  6325:             var reg = new RegExp("^supplemental");
                   6326:             if (pageId == 'mainCourseDocuments') {
1.434     raeburn  6327:                 if (storedpage == 1) {
                   6328:                     document.simpleedit.folderpath.value = '';
                   6329:                     document.uploaddocument.folderpath.value = '';
                   6330:                 } else {
                   6331:                     if (reg.test(storedpath)) {
                   6332:                         document.simpleedit.folderpath.value = '$toplevelmain';
                   6333:                         document.uploaddocument.folderpath.value = '$toplevelmain';
                   6334:                         document.newext.folderpath.value = '$toplevelmain';
                   6335:                     } else {
                   6336:                         document.simpleedit.folderpath.value = storedpath;
                   6337:                         document.uploaddocument.folderpath.value = storedpath;
                   6338:                         document.newext.folderpath.value = storedpath;
                   6339:                     }
1.433     raeburn  6340:                 }
                   6341:             } else {
1.434     raeburn  6342:                 if (reg.test(storedpath)) {
                   6343:                     document.simpleedit.folderpath.value = storedpath;
                   6344:                     document.supuploaddocument.folderpath.value = storedpath;
                   6345:                     document.supnewext.folderpath.value = storedpath;
                   6346:                 } else {
1.433     raeburn  6347:                     document.simpleedit.folderpath.value = '$toplevelsupp';
                   6348:                     document.supuploaddocument.folderpath.value = '$toplevelsupp';
                   6349:                     document.supnewext.folderpath.value = '$toplevelsupp';
                   6350:                 }
                   6351:             }
                   6352:         }
1.485     raeburn  6353:         resize_scrollbox('contentscroll','1','0');
1.330     tempelho 6354: 	return false;
                   6355: }
1.329     droeschl 6356: 
1.472     raeburn  6357: function toContents(jumpto) {
                   6358:     var newurl = '$backtourl';
1.525     raeburn  6359:     if ((newurl == '/adm/navmaps') && (jumpto != '')) {
1.472     raeburn  6360:         newurl = newurl+'?postdata='+jumpto;
                   6361:     }
                   6362:     location.href=newurl;
                   6363: }
                   6364: 
1.538     raeburn  6365: function togglePick(caller,value) {
                   6366:     var disp = 'none';
                   6367:     if (document.getElementById('multi'+caller)) {
                   6368:         var curr = document.getElementById('multi'+caller).style.display;
                   6369:         if (value == 1) {
                   6370:             disp='block';
                   6371:         }
                   6372:         if (curr == disp) {
                   6373:             return; 
                   6374:         }
                   6375:         document.getElementById('multi'+caller).style.display=disp;
                   6376:         if (value == 1) {
                   6377:             document.getElementById('more'+caller).innerHTML = '&nbsp;&nbsp;<a href="javascript:toggleCheckUncheck(\\''+caller+'\\',1);" style="text-decoration:none;">$lt{'more'}</a>'; 
                   6378:         } else {
                   6379:             document.getElementById('more'+caller).innerHTML = '';
                   6380:         }
                   6381:         if (caller == 'actions') { 
                   6382:             setClass(value);
                   6383:             setBoxes(value);
                   6384:         }
                   6385:     }
                   6386:     var showButton = multiSettings();
                   6387:     if (showButton != 1) {
                   6388:         showButton = multiActions();
                   6389:     }
                   6390:     if (document.getElementById('multisave')) {
                   6391:         if (showButton == 1) {
                   6392:             document.getElementById('multisave').style.display='block';
                   6393:         } else {
                   6394:             document.getElementById('multisave').style.display='none';
                   6395:         }
                   6396:     }
                   6397:     resize_scrollbox('contentscroll','1','1');
                   6398:     return;
                   6399: }
                   6400: 
                   6401: function toggleCheckUncheck(caller,more) {
                   6402:     if (more == 1) {
                   6403:         document.getElementById('more'+caller).innerHTML = '&nbsp;&nbsp;<a href="javascript:toggleCheckUncheck(\\''+caller+'\\',0);" style="text-decoration:none;">$lt{'less'}</a>';
                   6404:         document.getElementById('allfields'+caller).style.display='block';
                   6405:     } else {
                   6406:         document.getElementById('more'+caller).innerHTML = '&nbsp;&nbsp;<a href="javascript:toggleCheckUncheck(\\''+caller+'\\',1);" style="text-decoration:none;">$lt{'more'}</a>';
                   6407:         document.getElementById('allfields'+caller).style.display='none';
                   6408:     }
                   6409:     resize_scrollbox('contentscroll','1','1');
                   6410: }
                   6411: 
                   6412: function multiSettings() {
                   6413:     var inuse = 0;
                   6414:     var settingsform = document.togglemultsettings;
                   6415:     if (settingsform.showmultpick.length > 1) {
                   6416:         for (var i=0; i<settingsform.showmultpick.length; i++) {
                   6417:             if (settingsform.showmultpick[i].checked) {
                   6418:                 if (settingsform.showmultpick[i].value == 1) {
                   6419:                     inuse = 1;  
                   6420:                 }
                   6421:             }
                   6422:         }
                   6423:     }
                   6424:     return inuse;
                   6425: }
                   6426: 
                   6427: function multiActions() {
                   6428:     var inuse = 0;
                   6429:     var actionsform = document.togglemultactions;
                   6430:     if (actionsform.showmultpick.length > 1) {
                   6431:         for (var i=0; i<actionsform.showmultpick.length; i++) {
                   6432:             if (actionsform.showmultpick[i].checked) {
                   6433:                 if (actionsform.showmultpick[i].value == 1) {
                   6434:                     inuse = 1;
                   6435:                 }
                   6436:             }
                   6437:         }
                   6438:     }
                   6439:     return inuse;
                   6440: } 
                   6441: 
                   6442: function checkSubmits() {
                   6443:     var numchanges = 0;
                   6444:     var form = document.saveactions;
                   6445:     var doactions = multiActions();
1.542     raeburn  6446:     var cutwarnings = 0;
                   6447:     var remwarnings = 0;
1.538     raeburn  6448:     if (doactions == 1) {
                   6449:         var remidxlist = document.cumulativeactions.allremoveidx.value;
                   6450:         if ((remidxlist != '') && (remidxlist != null)) {
                   6451:             var remidxs = remidxlist.split(',');
                   6452:             for (var i=0; i<remidxs.length; i++) {
                   6453:                 if (document.getElementById('remove_'+remidxs[i])) {
                   6454:                     if (document.getElementById('remove_'+remidxs[i]).checked) {
                   6455:                         form.multiremove.value += remidxs[i]+',';
                   6456:                         numchanges ++;
1.542     raeburn  6457:                         if (document.getElementById('skip_remove_'+remidxs[i])) {
                   6458:                             if (document.getElementById('skip_remove_'+remidxs[i]).value == 0) {
                   6459:                                 remwarnings ++;
                   6460:                             }
                   6461:                         }
1.537     raeburn  6462:                     }
                   6463:                 }
1.538     raeburn  6464:             }
                   6465:         }
                   6466:         var cutidxlist = document.cumulativeactions.allcutidx.value;
                   6467:         if ((cutidxlist != '') && (cutidxlist != null)) {
                   6468:             var cutidxs = cutidxlist.split(',');
                   6469:             for (var i=0; i<cutidxs.length; i++) {
                   6470:                 if (document.getElementById('cut_'+cutidxs[i])) {
                   6471:                     if (document.getElementById('cut_'+cutidxs[i]).checked == true) {
                   6472:                         form.multicut.value += cutidxs[i]+',';
                   6473:                         numchanges ++;
1.542     raeburn  6474:                         if (document.getElementById('skip_cut_'+cutidxs[i])) {
                   6475:                             if (document.getElementById('skip_cut_'+cutidxs[i]).value == 0) {
                   6476:                                 cutwarnings ++;
                   6477:                             }
                   6478:                         }
1.537     raeburn  6479:                     }
                   6480:                 }
                   6481:             }
                   6482:         }
1.538     raeburn  6483:         var copyidxlist = document.cumulativeactions.allcopyidx.value;
                   6484:         if ((copyidxlist != '') && (copyidxlist != null)) {
                   6485:             var copyidxs = copyidxlist.split(',');
                   6486:             for (var i=0; i<copyidxs.length; i++) {
                   6487:                 if (document.getElementById('copy_'+copyidxs[i])) {
                   6488:                     if (document.getElementById('copy_'+copyidxs[i]).checked) {
                   6489:                         form.multicopy.value += copyidxs[i]+',';
                   6490:                         numchanges ++;
                   6491:                     }
                   6492:                 }
                   6493:             }
                   6494:         }
                   6495:         if (numchanges > 0) {
                   6496:             form.multichange.value = numchanges;
                   6497:         }
1.537     raeburn  6498:     }
1.538     raeburn  6499:     var dosettings = multiSettings();
1.543     raeburn  6500:     var haschanges = 0;
1.538     raeburn  6501:     if (dosettings == 1) {
                   6502:         form.allencrypturl.value = '';
                   6503:         form.allhiddenresource.value = '';
1.543     raeburn  6504:         form.changeparms.value = 'all';
                   6505:         var patt=new RegExp(",\$");
1.538     raeburn  6506:         var allidxlist = document.cumulativesettings.allidx.value;
                   6507:         if ((allidxlist != '') && (allidxlist != null)) {
                   6508:             var allidxs = allidxlist.split(',');
                   6509:             if (allidxs.length > 1) {
                   6510:                 for (var i=0; i<allidxs.length; i++) {
                   6511:                     if (document.getElementById('hiddenresource_'+allidxs[i])) {
                   6512:                         if (document.getElementById('hiddenresource_'+allidxs[i]).checked) {
                   6513:                             form.allhiddenresource.value += allidxs[i]+',';
                   6514:                         }
                   6515:                     }
                   6516:                     if (document.getElementById('encrypturl_'+allidxs[i])) {
                   6517:                         if (document.getElementById('encrypturl_'+allidxs[i]).checked) {
                   6518:                             form.allencrypturl.value += allidxs[i]+',';
                   6519:                         }
                   6520:                     }
                   6521:                 }
1.543     raeburn  6522:                 form.allhiddenresource.value = form.allhiddenresource.value.replace(patt,"");
                   6523:                 form.allencrypturl.value = form.allencrypturl.value.replace(patt,"");
1.537     raeburn  6524:             }
1.538     raeburn  6525:         }
                   6526:         form.allrandompick.value = '';
                   6527:         form.allrandomorder.value = '';
                   6528:         var allmapidxlist = document.cumulativesettings.allmapidx.value;
                   6529:         if ((allmapidxlist != '') && (allmapidxlist != null)) {
                   6530:             var allmapidxs = allmapidxlist.split(',');
                   6531:             for (var i=0; i<allmapidxs.length; i++) {
                   6532:                 var randompick = document.getElementById('randompick_'+allmapidxs[i]);
                   6533:                 var rpicknum = document.getElementById('rpicknum_'+allmapidxs[i]);
                   6534:                 var randorder = document.getElementById('randomorder_'+allmapidxs[i]);
                   6535:                 if ((randompick.checked) && (rpicknum.value != '')) {
                   6536:                     form.allrandompick.value += allmapidxs[i]+':'+rpicknum.value+',';
                   6537:                 }
                   6538:                 if (randorder.checked) {
                   6539:                     form.allrandomorder.value += allmapidxs[i]+',';
                   6540:                 }
1.537     raeburn  6541:             }
1.543     raeburn  6542:             form.allrandompick.value = form.allrandompick.value.replace(patt,"");
                   6543:             form.allrandomorder.value = form.allrandomorder.value.replace(patt,"");
                   6544:         }
                   6545:         if (document.cumulativesettings.currhiddenresource.value != form.allhiddenresource.value) {
                   6546:             haschanges = 1;
                   6547:         }
                   6548:         if (document.cumulativesettings.currencrypturl.value != form.allencrypturl.value) {
                   6549:             haschanges = 1;
                   6550:         }
                   6551:         if (document.cumulativesettings.currrandomorder.value != form.allrandomorder.value) {
                   6552:             haschanges = 1;
                   6553:         }
                   6554:         if (document.cumulativesettings.currrandompick.value != form.allrandompick.value) {
                   6555:             haschanges = 1;
1.537     raeburn  6556:         }
                   6557:     }
1.543     raeburn  6558:     if (doactions == 1) {
1.542     raeburn  6559:         if (numchanges > 0) {
                   6560:             if ((cutwarnings > 0) || (remwarnings > 0)) {
                   6561:                 if (remwarnings > 0) {
                   6562:                     if (!confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr3a"} '+remwarnings+' $lt{"p_rmr3b"}')) {
                   6563:                         return false;
                   6564:                     }
                   6565:                 }
                   6566:                 if (cutwarnings > 0) {
                   6567:                     if (!confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr3a"} '+cutwarnings+' $lt{"p_ctr3b"}')) {
                   6568:                         return false;
                   6569:                     }
                   6570:                 }
                   6571:             }
                   6572:             form.submit();
                   6573:             return true;
1.543     raeburn  6574:         }
                   6575:     }
                   6576:     if (dosettings == 1) {
                   6577:         if (haschanges == 1) {
1.542     raeburn  6578:             form.submit();
                   6579:             return true;
                   6580:         }
1.543     raeburn  6581:     }
                   6582:     if ((dosettings == 1) && (doactions == 1)) {
                   6583:         alert("$lt{'noor'}");
                   6584:     } else {
                   6585:         if (dosettings == 1) {
                   6586:             alert("$lt{'noch'}");
                   6587:         } else {
                   6588:             alert("$lt{'noac'}");
                   6589:         }
                   6590:     }
1.538     raeburn  6591:     return false;
                   6592: }
                   6593: 
                   6594: function setClass(value) {
                   6595:     var cutclass = 'LC_docs_cut';
                   6596:     var copyclass = 'LC_docs_copy';
                   6597:     var removeclass = 'LC_docs_remove';
                   6598:     var cutreg = new RegExp("\\\\b"+cutclass+"\\\\b");
                   6599:     var copyreg = new RegExp("\\\\b"+copyclass+"\\\\b");
                   6600:     var removereg = new RegExp("\\\\"+removeclass+"\\\\b");
                   6601:     var links = document.getElementsByTagName('a');
                   6602:     for (var i=0; i<links.length; i++) {
                   6603:         var classes = links[i].className;
                   6604:         if (cutreg.test(classes)) {
                   6605:             links[i].className = cutclass;
                   6606:             if (value == 1) {
                   6607:                 links[i].className += " LC_menubuttons_link";
                   6608:             }
                   6609:         } else {
                   6610:             if (copyreg.test(classes)) {
                   6611:                 links[i].className = copyclass;
                   6612:                 if (value == 1) {
                   6613:                     links[i].className += " LC_menubuttons_link";
                   6614:                 } 
                   6615:             } else {
                   6616:                 if (removereg.test(classes)) {
                   6617:                     links[i].className = removeclass;
                   6618:                     if (value == 1) {
                   6619:                         links[i].className += " LC_menubuttons_link";
                   6620:                     }
                   6621:                 }
                   6622:             }
                   6623:         }
                   6624:     }
                   6625:     return;
1.537     raeburn  6626: }
                   6627: 
1.538     raeburn  6628: function setBoxes(value) {
                   6629:     var remidxlist = document.cumulativeactions.allremoveidx.value;
                   6630:     if ((remidxlist != '') && (remidxlist != null)) {
                   6631:         var remidxs = remidxlist.split(',');
                   6632:         for (var i=0; i<remidxs.length; i++) {
                   6633:             if (document.getElementById('remove_'+remidxs[i])) {
                   6634:                 var item = document.getElementById('remove_'+remidxs[i]);
                   6635:                 if (value == 1) {
                   6636:                     item.className = 'LC_docs_remove';
                   6637:                 } else {
                   6638:                     item.className = 'LC_hidden';
                   6639:                 }
                   6640:             }
                   6641:         }
                   6642:     }
                   6643:     var cutidxlist = document.cumulativeactions.allcutidx.value;
                   6644:     if ((cutidxlist != '') && (cutidxlist != null)) {
                   6645:         var cutidxs = cutidxlist.split(',');
                   6646:         for (var i=0; i<cutidxs.length; i++) {
                   6647:             if (document.getElementById('cut_'+cutidxs[i])) {
                   6648:                 var item = document.getElementById('cut_'+cutidxs[i]);
                   6649:                 if (value == 1) {
                   6650:                     item.className = 'LC_docs_cut';
                   6651:                 } else {
                   6652:                     item.className = 'LC_hidden';
                   6653:                 }
                   6654:             }
1.537     raeburn  6655:         }
                   6656:     }
1.538     raeburn  6657:     var copyidxlist = document.cumulativeactions.allcopyidx.value;
                   6658:     if ((copyidxlist != '') && (copyidxlist != null)) {
                   6659:         var copyidxs = copyidxlist.split(',');
                   6660:         for (var i=0; i<copyidxs.length; i++) {
                   6661:             if (document.getElementById('copy_'+copyidxs[i])) {
                   6662:                 var item = document.getElementById('copy_'+copyidxs[i]);
                   6663:                 if (value == 1) {
                   6664:                     item.className = 'LC_docs_copy';
                   6665:                 } else {
                   6666:                     item.className = 'LC_hidden';
                   6667:                 }
                   6668:             }
1.537     raeburn  6669:         }
                   6670:     }
                   6671:     return;
                   6672: }
                   6673: 
1.329     droeschl 6674: ENDNEWSCRIPT
                   6675: }
1.457     raeburn  6676: 
1.483     raeburn  6677: sub history_tab_js {
                   6678:     return <<"ENDHIST";
                   6679: function toggleHistoryDisp(choice) {
                   6680:     document.docslogform.docslog.value = choice;
                   6681:     document.docslogform.submit();
                   6682:     return;
                   6683: }
                   6684: 
                   6685: ENDHIST
                   6686: }
                   6687: 
1.484     raeburn  6688: sub inject_data_js {
                   6689:     return <<ENDINJECT;
                   6690: 
                   6691: function injectData(current, hiddenField, name, value) {
                   6692:         currentElement = document.getElementById(hiddenField);
                   6693:         currentElement.name = name;
                   6694:         currentElement.value = value;
                   6695:         current.submit();
                   6696: }
                   6697: 
                   6698: ENDINJECT
                   6699: }
                   6700: 
                   6701: sub dump_switchserver_js {
                   6702:     my @hosts = @_;
                   6703:     my %lt = &Apache::lonlocal::texthash(
1.574     raeburn  6704:         dump => 'Copying content to Authoring Space requires switching server.',
1.484     raeburn  6705:         swit => 'Switch server?',
1.568     raeburn  6706:         duco => 'Copying Content to Authoring Space',
1.484     raeburn  6707:         yone => 'You need to switch to a server housing an Authoring Space for which you are author or co-author.',
                   6708:         chos => 'Choose server',
                   6709:     );
                   6710:     my $role = $env{'request.role'};
                   6711:     my $js = <<"ENDSWJS";
                   6712: <script type="text/javascript">
                   6713: function write_switchserver() {
                   6714:     var server;
                   6715:     if (document.setserver.posshosts.length > 0) {
                   6716:         for (var i=0; i<document.setserver.posshosts.length; i++) {
                   6717:             if (document.setserver.posshosts[i].checked) {
                   6718:                 server = document.setserver.posshosts[i].value;
                   6719:             }
                   6720:        }
                   6721:        opener.document.location.href="/adm/switchserver?otherserver="+server+"&role=$role&origurl=/adm/coursedocs";
                   6722:     }
                   6723:     window.close();
                   6724: }
                   6725: </script>
                   6726: 
                   6727: ENDSWJS
                   6728: 
                   6729:     my $startpage = &Apache::loncommon::start_page('Choose server',$js,
                   6730:                                                    {'only_body' => 1,
                   6731:                                                     'js_ready'  => 1,});
                   6732:     my $endpage = &Apache::loncommon::end_page({'js_ready'  => 1});
                   6733: 
                   6734:     my $hostpicker;
                   6735:     my $count = 0;
                   6736:     foreach my $host (sort(@hosts)) {
                   6737:         my $checked;
                   6738:         if ($count == 0) {
                   6739:             $checked = ' checked="checked"';
                   6740:         }
                   6741:         $hostpicker .= '<label><input type="radio" name="posshosts" value="'.
                   6742:                        $host.'"'.$checked.' />'.$host.'</label>&nbsp;&nbsp;';
                   6743:         $count++;
                   6744:     }
                   6745:     
                   6746:     return <<"ENDSWITCHJS";
                   6747: 
                   6748: function dump_needs_switchserver(url) {
                   6749:     if (url!='' && url!= null) {
                   6750:         if (confirm("$lt{'dump'}\\n$lt{'swit'}")) {
                   6751:             go(url);
                   6752:         }
                   6753:     }
                   6754:     return;
                   6755: }
                   6756: 
                   6757: function choose_switchserver_window() {
                   6758:     newWindow = window.open('','ChooseServer','height=400,width=500,scrollbars=yes')
                   6759:     newWindow.document.open();
                   6760:     newWindow.document.writeln('$startpage');
                   6761:     newWindow.document.write('<h3>$lt{'duco'}<\\/h3>\\n'+
                   6762:        '<p>$lt{'yone'}<\\/p>\\n'+
                   6763:        '<div class="LC_left_float"><fieldset><legend>$lt{'chos'}<\\/legend>\\n'+
                   6764:        '<form name="setserver" method="post" action="" \\/>\\n'+
                   6765:        '$hostpicker\\n'+
                   6766:        '<br \\/><br \\/>\\n'+
                   6767:        '<input type="button" name="makeswitch" value="$lt{'swit'}" '+
                   6768:        'onclick="write_switchserver();" \\/>\\n'+
                   6769:        '<\\/form><\\/fieldset><\\/div><br clear="all" \\/>\\n');
                   6770:     newWindow.document.writeln('$endpage');
                   6771:     newWindow.document.close();
                   6772:     newWindow.focus();
                   6773: }
                   6774: 
                   6775: ENDSWITCHJS
                   6776: }
                   6777: 
                   6778: sub makedocslogform {
                   6779:     my ($formelems,$docslog) = @_;
                   6780:     return <<"LOGSFORM";
                   6781:  <form action="/adm/coursedocs" method="post" name="docslogform">
                   6782:    <input type="hidden" name="docslog" value="$docslog" />
                   6783:    $formelems
                   6784:  </form>
                   6785: LOGSFORM
                   6786: }
                   6787: 
                   6788: sub makesimpleeditform {
                   6789:     my ($formelems) = @_;
                   6790:     return <<"SIMPFORM";
                   6791:  <form name="simpleedit" method="post" action="/adm/coursedocs">
                   6792:    <input type="hidden" name="importdetail" value="" />
                   6793:    $formelems
                   6794:  </form>
                   6795: SIMPFORM
                   6796: }
                   6797: 
1.329     droeschl 6798: 1;
                   6799: __END__
                   6800: 
                   6801: 
                   6802: =head1 NAME
                   6803: 
                   6804: Apache::londocs.pm
                   6805: 
                   6806: =head1 SYNOPSIS
                   6807: 
                   6808: This is part of the LearningOnline Network with CAPA project
                   6809: described at http://www.lon-capa.org.
                   6810: 
                   6811: =head1 SUBROUTINES
                   6812: 
                   6813: =over
                   6814: 
                   6815: =item %help=()
                   6816: 
                   6817: Available help topics
                   6818: 
                   6819: =item mapread()
                   6820: 
1.344     bisitz   6821: Mapread read maps into LONCAPA::map:: global arrays
1.329     droeschl 6822: @order and @resources, determines status
                   6823: sets @order - pointer to resources in right order
                   6824: sets @resources - array with the resources with correct idx
                   6825: 
                   6826: =item authorhosts()
                   6827: 
                   6828: Return hash with valid author names
                   6829: 
                   6830: =item clean()
                   6831: 
                   6832: =item dumpcourse()
                   6833: 
                   6834:     Actually dump course
                   6835: 
                   6836: =item group_import()
                   6837: 
                   6838:     Imports the given (name, url) resources into the course
                   6839:     coursenum, coursedom, and folder must precede the list
                   6840: 
                   6841: =item breadcrumbs()
                   6842: 
                   6843: =item log_docs()
                   6844: 
                   6845: =item docs_change_log()
                   6846: 
                   6847: =item update_paste_buffer()
                   6848: 
                   6849: =item print_paste_buffer()
                   6850: 
                   6851: =item do_paste_from_buffer()
                   6852: 
1.538     raeburn  6853: =item do_buffer_empty() 
                   6854: 
                   6855: =item clear_from_buffer()
                   6856: 
1.492     raeburn  6857: =item get_newmap_url()
                   6858: 
                   6859: =item dbcopy()
                   6860: 
                   6861: =item uniqueness_check()
                   6862: 
                   6863: =item contained_map_check()
                   6864: 
                   6865: =item url_paste_fixups()
                   6866: 
                   6867: =item apply_fixups()
                   6868: 
                   6869: =item copy_dependencies()
                   6870: 
1.329     droeschl 6871: =item update_parameter()
                   6872: 
                   6873: =item handle_edit_cmd()
                   6874: 
                   6875: =item editor()
                   6876: 
                   6877: =item process_file_upload()
                   6878: 
                   6879: =item process_secondary_uploads()
                   6880: 
                   6881: =item is_supplemental_title()
                   6882: 
                   6883: =item entryline()
                   6884: 
                   6885: =item tiehash()
                   6886: 
                   6887: =item untiehash()
                   6888: 
                   6889: =item checkonthis()
                   6890: 
                   6891: check on this
                   6892: 
                   6893: =item verifycontent()
                   6894: 
                   6895: Verify Content
                   6896: 
                   6897: =item devalidateversioncache() & checkversions()
                   6898: 
                   6899: Check Versions
                   6900: 
                   6901: =item mark_hash_old()
                   6902: 
                   6903: =item is_hash_old()
                   6904: 
                   6905: =item changewarning()
                   6906: 
                   6907: =item init_breadcrumbs()
                   6908: 
                   6909: Breadcrumbs for special functions
                   6910: 
1.484     raeburn  6911: =item create_list_elements()
                   6912: 
                   6913: =item create_form_ul()
                   6914: 
                   6915: =item startContentScreen() 
                   6916: 
                   6917: =item endContentScreen()
                   6918: 
                   6919: =item supplemental_base()
                   6920: 
                   6921: =item embedded_form_elems()
                   6922: 
                   6923: =item embedded_destination()
                   6924: 
                   6925: =item return_to_editor()
                   6926: 
                   6927: =item decompression_info()
                   6928: 
                   6929: =item decompression_phase_one()
                   6930: 
                   6931: =item decompression_phase_two()
                   6932: 
                   6933: =item remove_archive()
                   6934: 
                   6935: =item generate_admin_menu()
                   6936: 
                   6937: =item generate_edit_table()
                   6938: 
                   6939: =item editing_js()
                   6940: 
                   6941: =item history_tab_js()
                   6942: 
                   6943: =item inject_data_js()
                   6944: 
                   6945: =item dump_switchserver_js()
                   6946: 
1.485     raeburn  6947: =item resize_scrollbox_js()
1.484     raeburn  6948: 
                   6949: =item makedocslogform()
                   6950: 
1.485     raeburn  6951: =item makesimpleeditform()
                   6952: 
1.329     droeschl 6953: =back
                   6954: 
                   6955: =cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.