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

1.1       www         1: # The LearningOnline Network
1.2       www         2: # Documents
1.1       www         3: #
1.288   ! albertel    4: # $Id: londocs.pm,v 1.287 2007/07/07 00:53:24 albertel Exp $
1.1       www         5: #
1.3       www         6: # Copyright Michigan State University Board of Trustees
1.1       www         7: #
1.3       www         8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
1.1       www         9: #
1.3       www        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.
1.1       www        14: #
1.3       www        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: 
1.2       www        29: package Apache::londocs;
1.1       www        30: 
                     31: use strict;
1.28      www        32: use Apache::Constants qw(:common :http);
1.158     raeburn    33: use Apache::imsexport;
1.4       www        34: use Apache::lonnet;
                     35: use Apache::loncommon;
1.245     albertel   36: use LONCAPA::map();
                     37: use Apache::lonratedt();
1.15      www        38: use Apache::lonxml;
1.244     albertel   39: use Apache::lonclonecourse;
1.138     raeburn    40: use Apache::lonnavmaps;
1.38      www        41: use HTML::Entities;
1.27      www        42: use GDBM_File;
1.81      www        43: use Apache::lonlocal;
1.143     raeburn    44: use Cwd;
1.264     albertel   45: use LONCAPA qw(:DEFAULT :match);
1.7       www        46: 
1.8       www        47: my $iconpath;
1.7       www        48: 
1.27      www        49: my %hash;
                     50: 
                     51: my $hashtied;
1.29      www        52: my %alreadyseen=();
1.27      www        53: 
1.40      www        54: my $hadchanges;
                     55: 
1.47      www        56: # Available help topics
                     57: 
                     58: my %help=();
                     59: 
1.245     albertel   60: # Mapread read maps into LONCAPA::map:: global arrays 
1.10      www        61: # @order and @resources, determines status
1.7       www        62: # sets @order - pointer to resources in right order
                     63: # sets @resources - array with the resources with correct idx
                     64: #
                     65: 
                     66: sub mapread {
                     67:     my ($coursenum,$coursedom,$map)=@_;
                     68:     return
1.245     albertel   69:       &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
                     70: 			     $map);
1.7       www        71: }
                     72: 
                     73: sub storemap {
                     74:     my ($coursenum,$coursedom,$map)=@_;
1.104     albertel   75:     my ($outtext,$errtext)=
1.245     albertel   76:       &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
                     77: 			      $map,1);
1.104     albertel   78:     if ($errtext) { return ($errtext,2); }
                     79:     
                     80:     $hadchanges=1;
                     81:     return ($errtext,0);
1.7       www        82: }
                     83: 
1.74      www        84: # ----------------------------------------- Return hash with valid author names
                     85: 
                     86: sub authorhosts {
                     87:     my %outhash=();
                     88:     my $home=0;
                     89:     my $other=0;
1.174     albertel   90:     foreach (keys %env) {
1.74      www        91: 	if ($_=~/^user\.role\.(au|ca)\.(.+)$/) {
                     92: 	    my $role=$1;
                     93: 	    my $realm=$2;
1.174     albertel   94: 	    my ($start,$end)=split(/\./,$env{$_});
1.74      www        95: 	    if (($start) && ($start>time)) { next; }
                     96: 	    if (($end) && (time>$end)) { next; }
                     97: 	    my $ca; my $cd;
                     98: 	    if ($1 eq 'au') {
1.174     albertel   99: 		$ca=$env{'user.name'};
                    100: 		$cd=$env{'user.domain'};
1.74      www       101: 	    } else {
1.264     albertel  102: 		($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
1.74      www       103: 	    }
1.107     albertel  104: 	    my $allowed=0;
                    105: 	    my $myhome=&Apache::lonnet::homeserver($ca,$cd);
                    106: 	    my @ids=&Apache::lonnet::current_machine_ids();
                    107: 	    foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } }
                    108: 	    if ($allowed) {
1.74      www       109: 		$home++;
                    110: 		$outhash{'home_'.$ca.'@'.$cd}=1;
                    111: 	    } else {
1.107     albertel  112: 		$outhash{'otherhome_'.$ca.'@'.$cd}=$myhome;
1.74      www       113: 		$other++;
                    114: 	    }
                    115: 	}
                    116:     }
                    117:     return ($home,$other,%outhash);
                    118: }
                    119: # ------------------------------------------------------ Generate "dump" button
                    120: 
                    121: sub dumpbutton {
                    122:     my ($home,$other,%outhash)=&authorhosts();
1.230     albertel  123:     my $type = &Apache::loncommon::course_type();
1.74      www       124:     if ($home+$other==0) { return ''; }
                    125:     if ($home) {
1.283     albertel  126: 	return '<div>'.
1.81      www       127: 	    '<input type="submit" name="dumpcourse" value="'.
1.230     albertel  128: 	    &mt('Dump '.$type.' DOCS to Construction Space').'" />'.
1.283     albertel  129: 	    &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs').
                    130: 	    '</div>';
1.74      www       131:     } else {
1.283     albertel  132: 	return '<div>'.
1.230     albertel  133:      &mt('Dump '.$type.
1.283     albertel  134: 	 ' DOCS to Construction Space: available on other servers').
                    135: 	 '</div>';
1.74      www       136:     }
                    137: }
                    138: 
1.164     albertel  139: sub clean {
                    140:     my ($title)=@_;
                    141:     $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
                    142:     return $title;	
                    143: }
1.74      www       144: # -------------------------------------------------------- Actually dump course
                    145: 
                    146: sub dumpcourse {
1.224     albertel  147:     my ($r) = @_;
1.230     albertel  148:     my $type = &Apache::loncommon::course_type();
                    149:     $r->print(&Apache::loncommon::start_page('Dump '.$type.' DOCS to Construction Space').
                    150: 	      '<form name="dumpdoc" method="post">');
1.257     www       151:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Dump '.$type.' DOCS to Construction Space'));
1.74      www       152:     my ($home,$other,%outhash)=&authorhosts();
1.75      www       153:     unless ($home) { return ''; }
1.174     albertel  154:     my $origcrsid=$env{'request.course.id'};
1.76      www       155:     my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
1.174     albertel  156:     if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
1.76      www       157: # Do the dumping
1.174     albertel  158: 	unless ($outhash{'home_'.$env{'form.authorspace'}}) { return ''; }
                    159: 	my ($ca,$cd)=split(/\@/,$env{'form.authorspace'});
1.87      www       160: 	$r->print('<h3>'.&mt('Copying Files').'</h3>');
1.174     albertel  161: 	my $title=$env{'form.authorfolder'};
1.164     albertel  162: 	$title=&clean($title);
1.79      www       163: 	my %replacehash=();
1.174     albertel  164: 	foreach (keys %env) {
1.79      www       165: 	    if ($_=~/^form\.namefor\_(.+)/) {
1.174     albertel  166: 		$replacehash{$1}=$env{$_};
1.79      www       167: 	    }
                    168: 	}
1.174     albertel  169: 	my $crs='/uploaded/'.$env{'request.course.id'}.'/';
1.79      www       170: 	$crs=~s/\_/\//g;
                    171: 	foreach (keys %replacehash) {
                    172: 	    my $newfilename=$title.'/'.$replacehash{$_};
1.205     albertel  173: 	    $newfilename=~s/\.(\w+)$//;
                    174: 	    my $ext=$1;
1.164     albertel  175: 	    $newfilename=&clean($newfilename);
1.205     albertel  176: 	    $newfilename.='.'.$ext;
1.79      www       177: 	    my @dirs=split(/\//,$newfilename);
                    178: 	    my $path='/home/'.$ca.'/public_html';
                    179: 	    my $makepath=$path;
                    180: 	    my $fail=0;
                    181: 	    for (my $i=0;$i<$#dirs;$i++) {
                    182: 		$makepath.='/'.$dirs[$i];
                    183: 		unless (-e $makepath) { 
                    184: 		    unless(mkdir($makepath,0777)) { $fail=1; } 
                    185: 		}
                    186: 	    }
                    187: 	    $r->print('<br /><tt>'.$_.'</tt> => <tt>'.$newfilename.'</tt>: ');
                    188: 	    if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
                    189: 		if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
1.244     albertel  190: 		    print $fh &Apache::lonclonecourse::rewritefile(
                    191:          &Apache::lonclonecourse::readfile($env{'request.course.id'},$_),
1.79      www       192: 				     (%replacehash,$crs => '')
                    193: 								    );
                    194: 		} else {
                    195: 		    print $fh
1.244     albertel  196:          &Apache::lonclonecourse::readfile($env{'request.course.id'},$_);
1.79      www       197: 		       }
                    198: 		$fh->close();
                    199: 	    } else {
                    200: 		$fail=1;
                    201: 	    }
                    202: 	    if ($fail) {
1.283     albertel  203: 		$r->print('<span class="LC_error">'.&mt('fail').'</span>');
1.79      www       204: 	    } else {
1.283     albertel  205: 		$r->print('<span class="LC_success">'.&mt('ok').'</span>');
1.79      www       206: 	    }
                    207: 	}
1.76      www       208:     } else {
                    209: # Input form
                    210: 	unless ($home==1) {
                    211: 	    $r->print(
1.81      www       212: 		      '<h3>'.&mt('Select the Construction Space').'</h3><select name="authorspace">');
1.76      www       213: 	}
                    214: 	foreach (sort keys %outhash) {
                    215: 	    if ($_=~/^home_(.+)$/) {
                    216: 		if ($home==1) {
                    217: 		    $r->print(
                    218: 		  '<input type="hidden" name="authorspace" value="'.$1.'" />');
                    219: 		} else {
1.133     www       220: 		    $r->print('<option value="'.$1.'">'.$1.' - '.
                    221: 			      &Apache::loncommon::plainname(split(/\@/,$1)).'</option>');
1.76      www       222: 		}
                    223: 	    }
                    224: 	}
                    225: 	unless ($home==1) {
                    226: 	    $r->print('</select>');
                    227: 	}
                    228: 	my $title=$origcrsdata{'description'};
1.227     albertel  229: 	$title=~s/[\/\s]+/\_/gs;
1.164     albertel  230: 	$title=&clean($title);
1.81      www       231: 	$r->print('<h3>'.&mt('Folder in Construction Space').'</h3><input type="text" size="50" name="authorfolder" value="'.$title.'" /><br />');
1.76      www       232: 	&tiehash();
1.81      www       233: 	$r->print('<h3>'.&mt('Filenames in Construction Space').'</h3><table border="2"><tr><th>'.&mt('Internal Filename').'</th><th>'.&mt('Title').'</th><th>'.&mt('Save as ...').'</th></tr>');
1.244     albertel  234: 	foreach (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
1.78      www       235: 	    $r->print('<tr><td>'.$_.'</td>');
                    236: 	    my ($ext)=($_=~/\.(\w+)$/);
                    237: 	    my $title=$hash{'title_'.$hash{
                    238: 		'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}};
                    239: 	    $r->print('<td>'.($title?$title:'&nbsp;').'</td>');
1.235     albertel  240: 	    if (!$title) {
1.78      www       241: 		$title=$_;
1.235     albertel  242: 	    } else {
                    243: 		$title=~s|/|_|g;
1.78      www       244: 	    }
                    245: 	    $title=~s/\.(\w+)$//;
1.164     albertel  246: 	    $title=&clean($title);
1.78      www       247: 	    $title.='.'.$ext;
1.79      www       248: 	    $r->print("\n<td><input type='text' size='60' name='namefor_".$_."' value='".$title."' /></td></tr>\n");
1.76      www       249: 	}
1.78      www       250: 	$r->print("</table>\n");
1.76      www       251: 	&untiehash();
                    252: 	$r->print(
1.229     raeburn   253:   '<p><input type="submit" name="dumpcourse" value="'.&mt('Dump [_1] DOCS',$type).'" /></p></form>');
1.75      www       254:     }
1.74      www       255: }
1.76      www       256: 
1.138     raeburn   257: # ------------------------------------------------------ Generate "export" button
                    258: 
                    259: sub exportbutton {
1.230     albertel  260:     my $type = &Apache::loncommon::course_type();
1.283     albertel  261:     return '<div>'.
1.138     raeburn   262:             '<input type="submit" name="exportcourse" value="'.
1.230     albertel  263:             &mt('Export '.$type.' to IMS').'" />'.
1.283     albertel  264:     &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'</div>';
1.138     raeburn   265: }
                    266: 
                    267: sub exportcourse {
                    268:     my $r=shift;
1.230     albertel  269:     my $type = &Apache::loncommon::course_type();
1.138     raeburn   270:     my %discussiontime = &Apache::lonnet::dump('discussiontimes',
1.174     albertel  271:                                                $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'});
1.138     raeburn   272:     my $numdisc = keys %discussiontime;
                    273:     my $navmap = Apache::lonnavmaps::navmap->new();
                    274:     my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
                    275:     my $curRes;
1.143     raeburn   276:     my $outcome;
1.138     raeburn   277: 
                    278:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                    279:                                             ['finishexport']);
1.174     albertel  280:     if ($env{'form.finishexport'}) {
1.138     raeburn   281:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                    282:                                             ['archive','discussion']);
                    283: 
1.175     albertel  284:         my @exportitems = &Apache::loncommon::get_env_multiple('form.archive');
                    285:         my @discussions = &Apache::loncommon::get_env_multiple('form.discussion');
1.143     raeburn   286:         if (@exportitems == 0 && @discussions == 0) {
                    287:             $outcome = '<br />As you did not select any content items or discussions for export, an IMS package has not been created.  Please <a href="javascript:history.go(-1)">go back</a> to select either content items or discussions for export';
                    288:         } else {
                    289:             my $now = time;
                    290:             my %symbs;
                    291:             my $manifestok = 0;
                    292:             my $imsresources;
                    293:             my $tempexport;
                    294:             my $copyresult;
                    295:             my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport);
                    296:             if ($manifestok) {
1.157     raeburn   297:                 &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest);
1.143     raeburn   298:                 close($ims_manifest);
                    299: 
                    300: #Create zip file in prtspool
                    301:                 my $imszipfile = '/prtspool/'.
1.174     albertel  302:                 $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
1.143     raeburn   303:                    time.'_'.rand(1000000000).'.zip';
                    304:                 my $cwd = &Cwd::getcwd();
                    305:                 my $imszip = '/home/httpd/'.$imszipfile;
                    306:                 chdir $tempexport;
                    307:                 open(OUTPUT, "zip -r $imszip *  2> /dev/null |");
                    308:                 close(OUTPUT);
                    309:                 chdir $cwd;
1.230     albertel  310:                 $outcome .= &mt('Download the zip file from <a href="[_1]">IMS '.lc($type).' archive</a><br />',$imszipfile,);
1.143     raeburn   311:                 if ($copyresult) {
                    312:                     $outcome .= 'The following errors occurred during export - '.$copyresult;
1.138     raeburn   313:                 }
1.143     raeburn   314:             } else {
                    315:                 $outcome = '<br />Unfortunately you will not be able to retrieve an IMS archive of this posts at this time, because there was a problem creating a manifest file.<br />';
1.138     raeburn   316:             }
                    317:         }
1.229     raeburn   318:         $r->print(&Apache::loncommon::start_page('Export '.lc($type).' to IMS content package'));
1.257     www       319: 	$r->print(&Apache::lonhtmlcommon::breadcrumbs('Export '.lc($type).' to IMS content package'));
1.143     raeburn   320:         $r->print($outcome);
1.224     albertel  321:         $r->print(&Apache::loncommon::end_page());
1.138     raeburn   322:     } else {
                    323:         my $display;
                    324:         $display = '<form name="exportdoc" method="post">'."\n";
1.230     albertel  325:         $display .= &mt('Choose which items you wish to export from your '.$type.'.<br /><br />');
1.138     raeburn   326:         $display .= '<table border="0" cellspacing="0" cellpadding="3">'.
                    327:                     '<tr><td><fieldset><legend>&nbsp;<b>Content items</b></legend>'.
                    328:                     '<input type="button" value="check all" '.
                    329:                     'onclick="javascript:checkAll(document.exportdoc.archive)" />'.
                    330:                     '&nbsp;&nbsp;<input type="button" value="uncheck all"'.
                    331:                     ' onclick="javascript:uncheckAll(document.exportdoc.archive)" /></fieldset></td>'.
                    332:                     '<td>&nbsp;</td><td>&nbsp;</td>'.
                    333:                     '<td align="right"><fieldset><legend>&nbsp;<b>Discussion posts'.
                    334:                     '</b></legend><input type="button" value="check all"'.
                    335:                     ' onclick="javascript:checkAll(document.exportdoc.discussion)" />'.
                    336:                     '&nbsp;&nbsp;<input type="button" value="uncheck all"'.
                    337:                     ' onclick="javascript:uncheckAll(document.exportdoc.discussion)" /></fieldset></td>'.
                    338:                     '</tr></table>';
                    339:         my $curRes;
                    340:         my $depth = 0;
                    341:         my $count = 0;
                    342:         my $boards = 0;
                    343:         my $startcount = 5;
                    344:         my %parent = ();
                    345:         my %children = ();
                    346:         my $lastcontainer = $startcount;
                    347:         my @bgcolors = ('#F6F6F6','#FFFFFF');
                    348:         $display .= '<table cellspacing="0"><tr>'.
                    349:             '<td><b>Export content item?<br /></b></td><td>&nbsp;</td><td align="right">'."\n";
                    350:         if ($numdisc > 0) {
                    351:             $display.='<b>Export&nbsp;discussion posts?</b>'."\n";
                    352:         }
                    353:         $display.='&nbsp;</td></tr>';
                    354:         while ($curRes = $it->next()) {
                    355:             if (ref($curRes)) {
                    356:                 $count ++;
                    357:             }
                    358:             if ($curRes == $it->BEGIN_MAP()) {
                    359:                 $depth++;
                    360:                 $parent{$depth} = $lastcontainer;
                    361:             }
                    362:             if ($curRes == $it->END_MAP()) {
                    363:                 $depth--;
                    364:                 $lastcontainer = $parent{$depth};
                    365:             }
                    366:             if (ref($curRes)) {
                    367:                 my $symb = $curRes->symb();
1.158     raeburn   368:                 my $ressymb = $symb;
1.264     albertel  369:                 if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
1.158     raeburn   370:                     unless ($ressymb =~ m|adm/wrapper/adm|) {
                    371:                         $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
                    372:                     }
                    373:                 }
1.138     raeburn   374:                 my $color = $count%2;
                    375:                 $display .='<tr bgcolor='.$bgcolors[$color].'><td>'."\n".
                    376:                     '<input type="checkbox" name="archive" value="'.$count.'" ';
                    377:                 if (($curRes->is_sequence()) || ($curRes->is_page())) {
                    378:                     my $checkitem = $count + $boards + $startcount;
                    379:                     $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"';
                    380:                 }
                    381:                 $display .= ' />'."\n";
                    382:                 for (my $i=0; $i<$depth; $i++) {
1.282     albertel  383:                     $display .= '<img src="/adm/lonIcons/whitespace1.gif" class="LC_docs_spacer" /><img src="/adm/lonIcons/whitespace1.gif" class="LC_docs_spacer" />'."\n";
1.138     raeburn   384:                 }
                    385:                 if ($curRes->is_sequence()) {
                    386:                     $display .= '<img src="/adm/lonIcons/navmap.folder.open.gif">&nbsp;'."\n";
                    387:                     $lastcontainer = $count + $startcount + $boards;
                    388:                 } elsif ($curRes->is_page()) {
                    389:                     $display .= '<img src="/adm/lonIcons/navmap.page.open.gif">&nbsp;'."\n";
                    390:                     $lastcontainer = $count + $startcount + $boards;
                    391:                 }
                    392:                 my $currelem = $count+$boards+$startcount;
                    393:                 $children{$parent{$depth}} .= $currelem.':';
                    394:                 $display .= '&nbsp;'.$curRes->title().'</td>';
1.158     raeburn   395:                 if ($discussiontime{$ressymb} > 0) {
1.138     raeburn   396:                     $boards ++;
                    397:                     $currelem = $count+$boards+$startcount;
                    398:                     $display .= '<td>&nbsp;</td><td align="right"><input type="checkbox" name="discussion" value="'.$count.'" />&nbsp;</td>'."\n";
                    399:                 } else {
                    400:                     $display .= '<td colspan="2">&nbsp;</td>'."\n";
                    401:                 }
                    402:             }
                    403:         }
                    404:         my $scripttag = qq|
                    405: <script>
                    406: 
                    407: function checkAll(field) {
1.158     raeburn   408:     if (field.length > 0) {
                    409:         for (i = 0; i < field.length; i++) {
                    410:             field[i].checked = true ;
                    411:         }
                    412:     } else {
                    413:         field.checked = true
                    414:     }
1.138     raeburn   415: }
1.158     raeburn   416:                                                                                 
1.138     raeburn   417: function uncheckAll(field) {
1.158     raeburn   418:     if (field.length > 0) {
                    419:         for (i = 0; i < field.length; i++) {
                    420:             field[i].checked = false ;
                    421:         }
                    422:     } else {
                    423:         field.checked = false ;
                    424:     }
1.138     raeburn   425: }
                    426: 
                    427: function propagateCheck(item) {
                    428:     if (document.exportdoc.elements[item].checked == true) {
                    429:         containerCheck(item)
                    430:     }
                    431: } 
                    432: 
                    433: function containerCheck(item) {
                    434:     document.exportdoc.elements[item].checked = true
                    435:     var numitems = $count + $boards + $startcount
                    436:     var parents = new Array(numitems)
                    437:     for (var i=$startcount; i<numitems; i++) {
                    438:         parents[i] = new Array
                    439:     }
                    440:         |;
                    441: 
                    442:         foreach my $container (sort { $a <=> $b } keys %children) {
                    443:             my @contents = split/:/,$children{$container};
                    444:             for (my $i=0; $i<@contents; $i ++) {
                    445:                 $scripttag .= '    parents['.$container.']['.$i.'] = '.$contents[$i]."\n";
                    446:             }
                    447:         }
                    448: 
                    449:         $scripttag .= qq|
                    450:     if (parents[item].length > 0) {
                    451:         for (var j=0; j<parents[item].length; j++) {
                    452:             containerCheck(parents[item][j])
                    453:         }
                    454:      }   
                    455: }
                    456: 
                    457: </script>
                    458:         |;
1.229     raeburn   459: 	$r->print(&Apache::loncommon::start_page('Export '.lc($type).' to IMS content package',
1.224     albertel  460: 						 $scripttag));
1.257     www       461: 	$r->print(&Apache::lonhtmlcommon::breadcrumbs('Export '.lc($type).' to IMS content package'));
1.224     albertel  462: 	$r->print($display.'</table>'.
1.138     raeburn   463:                   '<p><input type="hidden" name="finishexport" value="1">'.
                    464:                   '<input type="submit" name="exportcourse" value="'.
1.230     albertel  465:                   &mt('Export '.$type.' DOCS').'" /></p></form>'.
1.224     albertel  466: 		  &Apache::loncommon::end_page());
1.138     raeburn   467:     }
                    468: }
                    469: 
1.143     raeburn   470: sub create_ims_store {
                    471:     my ($now,$manifestok,$outcome,$tempexport) = @_;
                    472:     $$tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';
                    473:     my $ims_manifest;
                    474:     if (!-e $$tempexport) {
                    475:         mkdir($$tempexport,0700);
                    476:     }
                    477:     $$tempexport .= '/'.$now;
                    478:     if (!-e $$tempexport) {
                    479:         mkdir($$tempexport,0700);
                    480:     }
1.174     albertel  481:     $$tempexport .= '/'.$env{'user.domain'}.'_'.$env{'user.name'};
1.143     raeburn   482:     if (!-e $$tempexport) {
                    483:         mkdir($$tempexport,0700);
                    484:     }
1.159     raeburn   485:     if (!-e "$$tempexport/resources") {
                    486:         mkdir("$$tempexport/resources",0700);
                    487:     }
1.143     raeburn   488: # open manifest file
                    489:     my $manifest = '/imsmanifest.xml';
                    490:     my $manifestfilename = $$tempexport.$manifest;
                    491:     if ($ims_manifest = Apache::File->new('>'.$manifestfilename)) {
                    492:         $$manifestok=1;
                    493:         print $ims_manifest
                    494: '<?xml version="1.0" encoding="UTF-8"?>'."\n".
                    495: '<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"'.
                    496: ' xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2"'.
                    497: ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'.
1.174     albertel  498: ' identifier="MANIFEST-'.$env{'request.course.id'}.'-'.$now.'"'.
1.143     raeburn   499: '  xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1imscp_v1p1.xsd'.
                    500: '  http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">'."\n".
1.199     raeburn   501: '  <metadata>
                    502:     <schema></schema>
                    503:     <imsmd:lom>
                    504:       <imsmd:general>
                    505:         <imsmd:identifier>'.$env{'request.course.id'}.'</imsmd:identifier>
                    506:         <imsmd:title>
                    507:           <imsmd:langstring xml:lang="en">'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</imsmd:langstring>
                    508:         </imsmd:title>
                    509:       </imsmd:general>
                    510:     </imsmd:lom>
                    511:   </metadata>'."\n".
1.174     albertel  512: '  <organizations default="ORG-'.$env{'request.course.id'}.'-'.$now.'">'."\n".
                    513: '    <organization identifier="ORG-'.$env{'request.course.id'}.'-'.$now.'"'.
1.143     raeburn   514: ' structure="hierarchical">'."\n".
1.199     raeburn   515: '      <title>'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</title>'
1.143     raeburn   516:     } else {
                    517:         $$outcome .= 'An error occurred opening the IMS manifest file.<br />'
                    518: ;
                    519:     }
                    520:     return $ims_manifest;
                    521: }
                    522: 
                    523: sub build_package {
                    524:     my ($now,$navmap,$exportitems,$discussions,$outcome,$tempexport,$copyresult,$ims_manifest) = @_;
                    525: # first iterator to look for dependencies
                    526:     my $it = $navmap->getIterator(undef,undef,undef,1,undef,undef);
                    527:     my $curRes;
                    528:     my $count = 0;
                    529:     my $depth = 0;
                    530:     my $lastcontainer = 0;
                    531:     my %parent = ();
                    532:     my @dependencies = ();
1.174     albertel  533:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    534:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.143     raeburn   535:     while ($curRes = $it->next()) {
                    536:         if (ref($curRes)) {
                    537:             $count ++;
                    538:         }
                    539:         if ($curRes == $it->BEGIN_MAP()) {
                    540:             $depth++;
                    541:             $parent{$depth} = $lastcontainer;
                    542:         }
                    543:         if ($curRes == $it->END_MAP()) {
                    544:             $depth--;
                    545:             $lastcontainer = $parent{$depth};
                    546:         }
                    547:         if (ref($curRes)) {
                    548:             if ($curRes->is_sequence() || $curRes->is_page()) {
                    549:                 $lastcontainer = $count;
                    550:             }
                    551:             if (grep/^$count$/,@$exportitems) {
                    552:                 &get_dependencies($exportitems,\%parent,$depth,\@dependencies);
                    553:             }
                    554:         }
                    555:     }
                    556: # second iterator to build manifest and store resources
                    557:     $it = $navmap->getIterator(undef,undef,undef,1,undef,undef);
                    558:     $depth = 0;
                    559:     my $prevdepth;
                    560:     $count = 0;
                    561:     my $imsresources;
                    562:     my $pkgdepth;
1.157     raeburn   563:     while ($curRes = $it->next()) {
                    564:         if ($curRes == $it->BEGIN_MAP()) {
                    565:             $prevdepth = $depth;
                    566:             $depth++;
                    567:         }
                    568:         if ($curRes == $it->END_MAP()) {
1.143     raeburn   569:             $prevdepth = $depth;
1.157     raeburn   570:             $depth--;
                    571:         }
                    572: 
                    573:         if (ref($curRes)) {
                    574:             $count ++;
                    575:             if ((grep/^$count$/,@$exportitems) || (grep/^$count$/,@dependencies)) {
                    576:                 my $symb = $curRes->symb();
                    577:                 my $isvisible = 'true';
                    578:                 my $resourceref;
                    579:                 if ($curRes->randomout()) {
                    580:                     $isvisible = 'false';
                    581:                 }
                    582:                 unless ($curRes->is_sequence()) {
1.174     albertel  583:                     $resourceref = 'identifierref="RES-'.$env{'request.course.id'}.'-'.$count.'"';
1.157     raeburn   584:                 }
1.199     raeburn   585:                 my $step = $prevdepth - $depth;
                    586:                 if (($step >= 0) && ($count > 1)) {
                    587:                     while ($step >= 0) {
                    588:                         print $ims_manifest "\n".'  </item>'."\n";
                    589:                         $step --;
                    590:                     }
1.157     raeburn   591:                 }
                    592:                 $prevdepth = $depth;
1.143     raeburn   593: 
1.157     raeburn   594:                 my $itementry =
1.174     albertel  595:               '<item identifier="ITEM-'.$env{'request.course.id'}.'-'.$count.
1.143     raeburn   596:               '" isvisible="'.$isvisible.'" '.$resourceref.'>'.
                    597:               '<title>'.$curRes->title().'</title>';
1.157     raeburn   598:                 print $ims_manifest "\n".$itementry;
1.143     raeburn   599: 
1.157     raeburn   600:                 unless ($curRes->is_sequence()) {
                    601:                     my $content_file;
                    602:                     my @hrefs = ();
                    603:                     &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport);
                    604:                     if ($content_file) {
                    605:                         $imsresources .= "\n".
1.174     albertel  606:                      '   <resource identifier="RES-'.$env{'request.course.id'}.'-'.$count.
1.143     raeburn   607:                      '" type="webcontent" href="'.$content_file.'">'."\n".
                    608:                      '       <file href="'.$content_file.'" />'."\n";
1.157     raeburn   609:                         foreach (@hrefs) {
                    610:                             $imsresources .=
1.143     raeburn   611:                      '        <file href="'.$_.'" />'."\n";
1.157     raeburn   612:                         }
1.158     raeburn   613:                         if (grep/^$count$/,@$discussions) {
                    614:                             my $ressymb = $symb;
                    615:                             my $mode;
1.264     albertel  616:                             if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
1.158     raeburn   617:                                 unless ($ressymb =~ m|adm/wrapper/adm|) {
                    618:                                     $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
                    619:                                 }
                    620:                                 $mode = 'board';
                    621:                             }
                    622:                             my %extras = (
                    623:                                           caller => 'imsexport',
1.159     raeburn   624:                                           tempexport => $tempexport.'/resources',
1.158     raeburn   625:                                           count => $count
                    626:                                          );
                    627:                             my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras);
                    628:                         }
1.157     raeburn   629:                         $imsresources .= '    </resource>'."\n";
1.143     raeburn   630:                     }
                    631:                 }
1.157     raeburn   632:                 $pkgdepth = $depth;
1.143     raeburn   633:             }
                    634:         }
                    635:     }
1.157     raeburn   636:     while ($pkgdepth > 0) {
1.143     raeburn   637:         print $ims_manifest "    </item>\n";
                    638:         $pkgdepth --;
                    639:     }
                    640:     my $resource_text = qq|
                    641:     </organization>
                    642:   </organizations>
                    643:   <resources>
                    644:     $imsresources
                    645:   </resources>
                    646: </manifest>
                    647:     |;
                    648:     print $ims_manifest $resource_text;
                    649: }
                    650: 
                    651: sub get_dependencies {
                    652:     my ($exportitems,$parent,$depth,$dependencies) = @_;
                    653:     if ($depth > 1) {
1.157     raeburn   654:         if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) {
1.143     raeburn   655:             push @$dependencies, $$parent{$depth};
                    656:             if ($depth > 2) {
                    657:                 &get_dependencies($exportitems,$parent,$depth-1,$dependencies);
                    658:             }
                    659:         }
                    660:     }
                    661: }
                    662: 
                    663: sub process_content {
                    664:     my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport) = @_;
                    665:     my $content_type;
                    666:     my $message;
1.158     raeburn   667:     my @uploads = ();
1.157     raeburn   668:     if ($curRes->is_sequence()) {
                    669:         $content_type = 'sequence';
                    670:     } elsif ($curRes->is_page()) {
                    671:         $content_type = 'page'; # need to handle individual items in pages.
1.143     raeburn   672:     } elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) {
                    673:         $content_type = 'syllabus';
1.158     raeburn   674:         my $contents = &Apache::imsexport::templatedpage($content_type);
                    675:         if ($contents) {
                    676:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    677:         }
1.157     raeburn   678:     } elsif ($symb =~ m-\.sequence___\d+___ext-) {
1.143     raeburn   679:         $content_type = 'external';
1.158     raeburn   680:         my $title = $curRes->title;
                    681:         my $contents =  &Apache::imsexport::external($symb,$title);
                    682:         if ($contents) {
                    683:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    684:         }
1.143     raeburn   685:     } elsif ($symb =~ m-adm/navmaps$-) {
                    686:         $content_type =  'navmap';
1.158     raeburn   687:     } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) {
1.143     raeburn   688:         $content_type = 'simplepage';
1.158     raeburn   689:         my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads);
                    690:         if ($contents) {
                    691:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    692:         }
                    693:     } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) {
1.143     raeburn   694:         $content_type = 'simpleproblem';
1.158     raeburn   695:         my $contents =  &Apache::imsexport::simpleproblem($symb);
                    696:         if ($contents) {
                    697:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    698:         }
1.188     raeburn   699:     } elsif ($symb =~ m-lib/templates/examupload\.problem$-) {
1.158     raeburn   700:         $content_type = 'examupload';
1.264     albertel  701:     } elsif ($symb =~ m-adm/($match_domain)/($match_username)/(\d+)/bulletinboard$-) {
1.143     raeburn   702:         $content_type = 'bulletinboard';
1.158     raeburn   703:         my $contents =  &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2);
                    704:         if ($contents) {
                    705:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    706:         }
                    707:     } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) {
1.143     raeburn   708:         $content_type = 'aboutme';
1.158     raeburn   709:         my $contents =  &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2);
                    710:         if ($contents) {
                    711:             $$content_file = &store_template($contents,$tempexport,$count,$content_type);
                    712:         }
1.157     raeburn   713:     } elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) {
                    714:         $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
1.162     raeburn   715:     } elsif ($symb =~ m-\.(sequence|page)___\d+___([^/]+)/([^/]+)-) {
1.143     raeburn   716:         my $canedit = 0;
1.174     albertel  717:         if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'})  {
1.143     raeburn   718:             $canedit= 1;
                    719:         }
1.200     raeburn   720: # only include problem code where current user is author
1.143     raeburn   721:         if ($canedit) {
1.157     raeburn   722:             $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource');
1.143     raeburn   723:         } else {
1.157     raeburn   724:             $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit');
1.143     raeburn   725:         }
1.162     raeburn   726:     } elsif ($symb =~ m-uploaded/$cdom/$cnum-) {
                    727:         $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
1.143     raeburn   728:     }
1.158     raeburn   729:     if (@uploads > 0) {
                    730:         foreach my $item (@uploads) {
                    731:             my $uploadmsg = '';
1.159     raeburn   732:             &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'templateupload');
1.158     raeburn   733:             if ($uploadmsg) {
                    734:                 $$copyresult .= $uploadmsg."\n";
                    735:             }
                    736:         }
                    737:     }
1.157     raeburn   738:     if ($message) {
                    739:         $$copyresult .= $message."\n";
                    740:     }
1.143     raeburn   741: }
                    742: 
                    743: sub replicate_content {
1.157     raeburn   744:     my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_;
1.159     raeburn   745:     my ($map,$ind,$url);
                    746:     if ($caller eq 'templateupload') {
                    747:         $url = $symb;
                    748:         $url =~ s#//#/#g;
                    749:     } else { 
                    750:         ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
                    751:     }
1.143     raeburn   752:     my $content;
                    753:     my $filename;
                    754:     my $repstatus;
1.157     raeburn   755:     my $content_name;
                    756:     if ($url =~ m-/([^/]+)$-) {
1.143     raeburn   757:         $filename = $1;
                    758:         if (!-e $tempexport.'/resources') {
                    759:             mkdir($tempexport.'/resources',0700);
                    760:         }
1.157     raeburn   761:         if (!-e $tempexport.'/resources/'.$count) {
1.143     raeburn   762:             mkdir($tempexport.'/resources/'.$count,0700);
                    763:         }
1.157     raeburn   764:         my $destination = $tempexport.'/resources/'.$count.'/'.$filename;
1.143     raeburn   765:         my $copiedfile;
                    766:         if ($copiedfile = Apache::File->new('>'.$destination)) {
                    767:             my $content;
1.157     raeburn   768:             if ($caller eq 'resource') {
1.197     raeburn   769:                 my $respath =  $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
                    770:                 my $filepath = &Apache::lonnet::filelocation($respath,$url);
                    771:                 $content = &Apache::lonnet::getfile($filepath);
1.143     raeburn   772:                 if ($content eq -1) {
                    773:                     $$message = 'Could not copy file '.$filename;
                    774:                 } else {
1.197     raeburn   775:                     &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource');
1.143     raeburn   776:                     $repstatus = 'ok';
                    777:                 }
1.162     raeburn   778:             } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') {
1.143     raeburn   779:                 my $rtncode;
1.157     raeburn   780:                 $repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode);
                    781:                 if ($repstatus eq 'ok') {
                    782:                     if ($url =~ /\.html?$/i) {
1.197     raeburn   783:                         &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
1.157     raeburn   784:                     }
                    785:                 } else {
1.197     raeburn   786:                     $$message = 'Could not render '.$url.' server message - '.$rtncode."<br />\n";
1.143     raeburn   787:                 }
1.162     raeburn   788:             } elsif ($caller eq 'noedit') {
                    789: # Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this. 
                    790:                 $repstatus = 'ok';
                    791:                 $content = 'Not the owner of this resource'; 
1.143     raeburn   792:             }
                    793:             if ($repstatus eq 'ok') {
                    794:                 print $copiedfile $content;
                    795:             }
                    796:             close($copiedfile);
                    797:         } else {
1.197     raeburn   798:             $$message = 'Could not open destination file for '.$filename."<br />\n";
1.143     raeburn   799:         }
                    800:     } else {
1.197     raeburn   801:         $$message = 'Could not determine name of file for '.$symb."<br />\n";
1.143     raeburn   802:     }
1.157     raeburn   803:     if ($repstatus eq 'ok') {
1.198     raeburn   804:         $content_name = 'resources/'.$count.'/'.$filename;
1.157     raeburn   805:     }
                    806:     return $content_name;
                    807: }
                    808: 
                    809: sub extract_media {
1.197     raeburn   810:     my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_;
1.198     raeburn   811:     my ($dirpath,$container);
1.197     raeburn   812:     my %allfiles = ();
                    813:     my %codebase = ();
1.198     raeburn   814:     if ($url =~ m-(.*/)([^/]+)$-) {
                    815:         $dirpath = $1;
                    816:         $container = $2;
                    817:     } else {
                    818:         $dirpath = $url;
                    819:         $container = '';
                    820:     }
1.197     raeburn   821:     &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content);
                    822:     foreach my $embed_file (keys(%allfiles)) {
                    823:         my $filename;
                    824:         if ($embed_file =~ m#([^/]+)$#) {
                    825:             $filename = $1;
                    826:         } else {
                    827:             $filename = $embed_file;
                    828:         }
                    829:         my $newname = 'res/'.$filename;
                    830:         my ($rtncode,$embed_content,$repstatus);
                    831:         my $embed_url;
                    832:         if ($embed_file =~ m-^/-) {
                    833:             $embed_url = $embed_file;           # points to absolute path
                    834:         } else {
                    835:             if ($embed_file =~ m-https?://-) {
                    836:                 next;                           # points to url
                    837:             } else {
1.198     raeburn   838:                 $embed_url = $dirpath.$embed_file;  # points to relative path
1.197     raeburn   839:             }
                    840:         }
                    841:         if ($caller eq 'resource') {
                    842:             my $respath =  $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';  
                    843:             my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url); 
                    844:             $embed_content = &Apache::lonnet::getfile($embed_path);
                    845:             unless ($embed_content eq -1) {
                    846:                 $repstatus = 'ok';
                    847:             }
                    848:         } elsif ($caller eq 'uploaded') {
                    849:             
                    850:             $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode);
                    851:         }
                    852:         if ($repstatus eq 'ok') {
                    853:             my $destination = $tempexport.'/resources/'.$count.'/res';
                    854:             if (!-e "$destination") {
                    855:                 mkdir($destination,0755);
                    856:             }
                    857:             $destination .= '/'.$filename;
                    858:             my $copiedfile;
                    859:             if ($copiedfile = Apache::File->new('>'.$destination)) {
                    860:                 print $copiedfile $embed_content;
1.198     raeburn   861:                 push @{$href}, 'resources/'.$count.'/res/'.$filename;
1.197     raeburn   862:                 my $attrib_regexp = '';
                    863:                 if (@{$allfiles{$embed_file}} > 1) {
                    864:                     $attrib_regexp = join('|',@{$allfiles{$embed_file}});
                    865:                 } else {
                    866:                     $attrib_regexp = $allfiles{$embed_file}[0];
                    867:                 }
                    868:                 $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi;
1.198     raeburn   869:                 if ($caller eq 'resource' && $container =~ /\.(problem|library)$/) {
1.197     raeburn   870:                     $$content =~ s#\Q$embed_file\E#$newname#gi;
                    871:                 }
                    872:             }
                    873:         } else {
                    874:             $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode."<br />\n";
                    875:         }
                    876:     }
1.157     raeburn   877:     return;
1.143     raeburn   878: }
1.74      www       879: 
1.158     raeburn   880: sub store_template {
                    881:     my ($contents,$tempexport,$count,$content_type) = @_;
                    882:     if ($contents) {
1.159     raeburn   883:         if ($tempexport) {
                    884:             if (!-e $tempexport.'/resources') {
                    885:                 mkdir($tempexport.'/resources',0700);
                    886:             }
                    887:             if (!-e $tempexport.'/resources/'.$count) {
                    888:                 mkdir($tempexport.'/resources/'.$count,0700);
                    889:             }
                    890:             my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml';
                    891:             my $storetemplate;
                    892:             if ($storetemplate = Apache::File->new('>'.$destination)) {
                    893:                 print $storetemplate $contents;
                    894:                 close($storetemplate);
                    895:             }
                    896:             if ($content_type eq 'external') {
1.198     raeburn   897:                 return 'resources/'.$count.'/'.$content_type.'.html';
1.159     raeburn   898:             } else {
1.198     raeburn   899:                 return 'resources/'.$count.'/'.$content_type.'.xml';
1.159     raeburn   900:             }
1.158     raeburn   901:         }
                    902:     }
                    903: }
                    904: 
1.73      bowersj2  905: # Imports the given (name, url) resources into the course
                    906: # coursenum, coursedom, and folder must precede the list
                    907: sub group_import {
1.277     albertel  908:     my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
                    909: 
                    910:     while (@files) {
1.287     albertel  911: 	my ($name, $url, $residx) = @{ shift(@files) };
1.277     albertel  912:         if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) 
                    913: 	     && ($caller eq 'londocs')
                    914: 	     && (!&Apache::lonnet::stat_file($url))) {
                    915: 	    
1.142     raeburn   916:             my $errtext = '';
                    917:             my $fatal = 0;
                    918:             my $newmapstr = '<map>'."\n".
                    919:                             '<resource id="1" src="" type="start"></resource>'."\n".
                    920:                             '<link from="1" to="2" index="1"></link>'."\n".
                    921:                             '<resource id="2" src="" type="finish"></resource>'."\n".
                    922:                             '</map>';
1.174     albertel  923:             $env{'form.output'}=$newmapstr;
1.189     albertel  924:             my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
1.142     raeburn   925:                                                 'output',$1.$2);
                    926:             if ($result != m|^/uploaded/|) {
                    927:                 $errtext.='Map not saved: A network error occured when trying to save the new map. ';
                    928:                 $fatal = 2;
                    929:             }
                    930:             if ($fatal) {
                    931:                 return ($errtext,$fatal);
                    932:             }
                    933:         }
1.73      bowersj2  934: 	if ($url) {
1.288   ! albertel  935: 	    if (!$residx 
        !           936: 		|| defined($LONCAPA::map::zombies[$residx])) {
        !           937: 		$residx = &LONCAPA::map::getresidx($url,$residx);
        !           938: 		push(@LONCAPA::map::order, $residx);
1.287     albertel  939: 	    }
1.73      bowersj2  940: 	    my $ext = 'false';
1.263     albertel  941: 	    if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
1.273     albertel  942: 	    $url  = &LONCAPA::map::qtunescape($url);
                    943: 	    $name = &LONCAPA::map::qtunescape($name);
1.287     albertel  944: 	    $LONCAPA::map::resources[$residx] = 
                    945: 		join(':', ($name, $url, $ext, 'normal', 'res'));
1.73      bowersj2  946: 	}
                    947:     }
1.142     raeburn   948:     return &storemap($coursenum, $coursedom, $folder.'.'.$container);
1.73      bowersj2  949: }
                    950: 
1.114     albertel  951: sub breadcrumbs {
                    952:     my ($where)=@_;
                    953:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.142     raeburn   954:     my (@folders);
1.174     albertel  955:     if ($env{'form.pagepath'}) {
                    956:         @folders = split('&',$env{'form.pagepath'});
1.142     raeburn   957:     } else {
1.174     albertel  958:         @folders=split('&',$env{'form.folderpath'});
1.142     raeburn   959:     }
1.116     albertel  960:     my $folderpath;
1.168     www       961:     my $cpinfo='';
1.251     www       962:     my $plain='';
1.242     www       963:     my $randompick=-1;
                    964:     my $isencrypted=0;
                    965:     my $ishidden=0;
1.116     albertel  966:     while (@folders) {
                    967: 	my $folder=shift(@folders);
                    968: 	my $foldername=shift(@folders);
                    969: 	if ($folderpath) {$folderpath.='&';}
                    970: 	$folderpath.=$folder.'&'.$foldername;
                    971: 	my $url='/adm/coursedocs?folderpath='.
1.228     www       972: 	    &escape($folderpath);
1.242     www       973:             my $name=&unescape($foldername);
                    974: # randompick number, hidden, encrypted is appended with ":"s to the foldername	
                    975:             $name=~s/\:(\d*)\:(\w*)\:(\w*)$//;
                    976:             if ($1 ne '') { 
                    977:                $randompick=$1;
                    978:             } else {
                    979:                $randompick=-1;
                    980:             }
                    981:             if ($2) { $ishidden=1; }
                    982:             if ($3) { $isencrypted=1; }
1.114     albertel  983: 	    &Apache::lonhtmlcommon::add_breadcrumb(
1.168     www       984: 		      {'href'=>$url.$cpinfo,
1.242     www       985: 		       'title'=>$name,
1.117     albertel  986: 		       'text'=>'<font size="+1">'.
1.266     albertel  987: 			   $name.'</font>',
                    988: 		       'no_mt'=>1,
1.117     albertel  989: 		       });
1.251     www       990: 	$plain.=$name.' &gt; ';
1.114     albertel  991:     }
1.251     www       992:     $plain=~s/\&gt\;\s*$//;
1.242     www       993:     return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp',
1.251     www       994: 					       'LC_docs_path'),$randompick,$ishidden,$isencrypted,$plain);
1.114     albertel  995: }
                    996: 
1.247     www       997: sub log_docs {
                    998:     return &Apache::lonnet::instructor_log('docslog',@_);
                    999: }
                   1000: 
                   1001: {
                   1002:     my @oldresources=();
                   1003:     my @oldorder=();
                   1004:     my $parmidx;
                   1005:     my %parmaction=();
                   1006:     my %parmvalue=();
1.249     www      1007:     my $changedflag;
1.247     www      1008: 
                   1009:     sub snapshotbefore {
1.248     albertel 1010:         @oldresources=@LONCAPA::map::resources;
                   1011:         @oldorder=@LONCAPA::map::order;
1.247     www      1012:         $parmidx=undef;
                   1013:         %parmaction=();
                   1014:         %parmvalue=();
1.249     www      1015:         $changedflag=0;
1.247     www      1016:     }
                   1017: 
                   1018:     sub remember_parms {
                   1019:         my ($idx,$parameter,$action,$value)=@_;
                   1020:         $parmidx=$idx;
                   1021:         $parmaction{$parameter}=$action;
                   1022:         $parmvalue{$parameter}=$value;
1.249     www      1023:         $changedflag=1;
1.247     www      1024:     }
                   1025: 
                   1026:     sub log_differences {
1.251     www      1027:         my ($plain)=@_;
1.260     www      1028:         my %storehash=('folder' => $plain,
                   1029:                        'currentfolder' => $env{'form.folder'});
1.247     www      1030:         if ($parmidx) {
                   1031:            $storehash{'parameter_res'}=$oldresources[$parmidx];
                   1032:            foreach my $parm (keys %parmaction) {
                   1033:               $storehash{'parameter_action_'.$parm}=$parmaction{$parm};
                   1034:               $storehash{'parameter_value_'.$parm}=$parmvalue{$parm};
                   1035:            }
                   1036:         }
                   1037:         my $maxidx=$#oldresources;
1.248     albertel 1038:         if ($#LONCAPA::map::resources>$#oldresources) {
                   1039:            $maxidx=$#LONCAPA::map::resources;
1.247     www      1040:         }
                   1041:         for (my $idx=0; $idx<=$maxidx; $idx++) {
                   1042:            if ($LONCAPA::map::resources[$idx] ne $oldresources[$idx]) {
                   1043:               $storehash{'before_resources_'.$idx}=$oldresources[$idx];
                   1044:               $storehash{'after_resources_'.$idx}=$LONCAPA::map::resources[$idx];
1.249     www      1045:               $changedflag=1;
1.247     www      1046:            }
                   1047:            if ($LONCAPA::map::order[$idx] ne $oldorder[$idx]) {
1.252     www      1048:               $storehash{'before_order_res_'.$idx}=$oldresources[$oldorder[$idx]];
                   1049:               $storehash{'after_order_res_'.$idx}=$LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
1.249     www      1050:               $changedflag=1;
1.247     www      1051:            }
                   1052:         }
1.251     www      1053: 	$storehash{'maxidx'}=$maxidx;
1.249     www      1054:         if ($changedflag) { &log_docs(\%storehash); }
1.247     www      1055:     }
                   1056: }
                   1057: 
                   1058: 
                   1059: #
                   1060: # Docs Change Log
                   1061: #
                   1062: sub docs_change_log {
                   1063:     my ($r)=@_;
1.260     www      1064:     my $folder=$env{'form.folder'};
1.247     www      1065:     $r->print(&Apache::loncommon::start_page('Course Document Change Log'));
                   1066:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Document Change Log'));
                   1067:     my %docslog=&Apache::lonnet::dump('nohist_docslog',
                   1068:                                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1069:                                       $env{'course.'.$env{'request.course.id'}.'.num'});
1.254     albertel 1070: 
1.247     www      1071:     if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); }
1.254     albertel 1072: 
1.247     www      1073:     $r->print('<form action="/adm/coursedocs" method="post" name="docslog">'.
                   1074:               '<input type="hidden" name="docslog" value="1" />');
1.254     albertel 1075: 
1.247     www      1076:     my %saveable_parameters = ('show' => 'scalar',);
                   1077:     &Apache::loncommon::store_course_settings('docs_log',
                   1078:                                               \%saveable_parameters);
                   1079:     &Apache::loncommon::restore_course_settings('docs_log',
                   1080:                                                 \%saveable_parameters);
                   1081:     if (!$env{'form.show'}) { $env{'form.show'}=10; }
1.254     albertel 1082:     my %lt=('hiddenresource' => 'Resources hidden',
                   1083: 	    'encrypturl'     => 'URL hidden',
                   1084: 	    'randompick'     => 'Randomly pick',
                   1085: 	    'set'            => 'set to',
                   1086: 	    'del'            => 'deleted');
1.259     www      1087:     $r->print(&Apache::loncommon::display_filter().
1.260     www      1088:               '<input type="hidden" name="folder" value="'.$folder.'" />'.
1.247     www      1089:               '<input type="submit" value="'.&mt('Display').'" /></form>');
                   1090:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.251     www      1091:               '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Folder').'</th><th>'.&mt('Before').'</th><th>'.
                   1092:               &mt('After').'</th>'.
1.247     www      1093:               &Apache::loncommon::end_data_table_header_row());
                   1094:     my $shown=0;
                   1095:     foreach my $id (sort { $docslog{$b}{'exe_time'}<=>$docslog{$a}{'exe_time'} } (keys(%docslog))) {
1.260     www      1096: 	if ($env{'form.displayfilter'} eq 'currentfolder') {
                   1097: 	    if ($docslog{$id}{'logentry'}{'currentfolder'} ne $folder) { next; }
                   1098: 	}
1.247     www      1099:         my @changes=keys(%{$docslog{$id}{'logentry'}});
1.261     www      1100:         if ($env{'form.displayfilter'} eq 'containing') {
                   1101: 	    my $wholeentry=$docslog{$id}{'exe_uname'}.':'.$docslog{$id}{'exe_udom'}.':'.
                   1102: 		&Apache::loncommon::plainname($docslog{$id}{'exe_uname'},$docslog{$id}{'exe_udom'});
                   1103: 	    foreach my $key (@changes) {
                   1104: 		$wholeentry.=':'.$docslog{$id}{'logentry'}{$key};
                   1105: 	    }
                   1106: 	    if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }         
                   1107: 	}
1.247     www      1108:         my $count = 0;
                   1109:         my $time =
                   1110:             &Apache::lonlocal::locallocaltime($docslog{$id}{'exe_time'});
                   1111:         my $plainname =
                   1112:             &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},
                   1113:                                           $docslog{$id}{'exe_udom'});
                   1114:         my $about_me_link =
                   1115:             &Apache::loncommon::aboutmewrapper($plainname,
                   1116:                                                $docslog{$id}{'exe_uname'},
                   1117:                                                $docslog{$id}{'exe_udom'});
                   1118:         my $send_msg_link='';
                   1119:         if ((($docslog{$id}{'exe_uname'} ne $env{'user.name'})
                   1120:              || ($docslog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
                   1121:             $send_msg_link ='<br />'.
                   1122:                 &Apache::loncommon::messagewrapper(&mt('Send message'),
                   1123:                                                    $docslog{$id}{'exe_uname'},
                   1124:                                                    $docslog{$id}{'exe_udom'});
                   1125:         }
                   1126:         $r->print(&Apache::loncommon::start_data_table_row());
                   1127:         $r->print('<td>'.$time.'</td>
                   1128:                        <td>'.$about_me_link.
                   1129:                   '<br /><tt>'.$docslog{$id}{'exe_uname'}.
                   1130:                                   ':'.$docslog{$id}{'exe_udom'}.'</tt>'.
1.249     www      1131:                   $send_msg_link.'</td><td>'.
1.251     www      1132:                   $docslog{$id}{'logentry'}{'folder'}.'</td><td>');
                   1133: # Before
                   1134: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1135: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                   1136: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
                   1137: 	    if ($oldname ne $newname) {
1.252     www      1138: 		$r->print(&LONCAPA::map::qtescape($oldname));
1.251     www      1139: 	    }
                   1140: 	}
1.252     www      1141: 	$r->print('<ul>');
                   1142: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1143:             if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) {
                   1144: 		$r->print('<li>'.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]).'</li>');
                   1145: 	    }
                   1146: 	}
                   1147: 	$r->print('</ul>');
1.251     www      1148: # After
                   1149:         $r->print('</td><td>');
                   1150: 
                   1151: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1152: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                   1153: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
1.279     albertel 1154: 	    if ($oldname ne '' && $oldname ne $newname) {
1.252     www      1155: 		$r->print(&LONCAPA::map::qtescape($newname));
1.251     www      1156: 	    }
                   1157: 	}        
1.252     www      1158: 	$r->print('<ul>');
                   1159: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1160:             if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) {
                   1161: 		$r->print('<li>'.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]).'</li>');
                   1162: 	    }
                   1163: 	}
                   1164: 	$r->print('</ul>');
                   1165: 	if ($docslog{$id}{'logentry'}{'parameter_res'}) {
                   1166: 	    $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':<ul>');
1.253     www      1167: 	    foreach my $parameter ('randompick','hiddenresource','encrypturl') {
1.252     www      1168: 		if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
1.254     albertel 1169: 		    $r->print('<li>'.
                   1170: 			      &mt($lt{$parameter}.' '.$lt{$docslog{$id}{'logentry'}{'parameter_action_'.$parameter}}.' [_1]',
                   1171: 				  $docslog{$id}{'logentry'}{'parameter_value_'.$parameter})
                   1172: 			      .'</li>');
1.252     www      1173: 		}
                   1174: 	    }
                   1175: 	    $r->print('</ul>');
                   1176: 	}
1.251     www      1177: # End
                   1178:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.247     www      1179:         $shown++;
                   1180:         if (!($env{'form.show'} eq &mt('all')
                   1181:               || $shown<=$env{'form.show'})) { last; }
                   1182:     }
                   1183:     $r->print(&Apache::loncommon::end_data_table());
                   1184: }
                   1185: 
1.281     albertel 1186: sub update_paste_buffer {
                   1187:     my ($coursenum,$coursedom) = @_;
                   1188: 
                   1189:     return if (!defined($env{'form.markcopy'}));
                   1190:     return if (!defined($env{'form.copyfolder'}));
                   1191:     return if ($env{'form.markcopy'} < 0);
                   1192: 
                   1193:     my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                   1194: 				    $env{'form.copyfolder'});
                   1195:     
                   1196:     return if ($fatal);
                   1197: 
                   1198: # Mark for copying
                   1199:     my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]);
                   1200:     if (&is_supplemental_title($title)) {
                   1201: 	($title) = &parse_supplemental_title($title);
                   1202:     }
1.287     albertel 1203:     $url=~s{http(&colon;|:)//https(&colon;|:)//}{https$2//};
                   1204: 
1.281     albertel 1205:     &Apache::lonnet::appenv('docs.markedcopy_title' => $title,
                   1206: 			    'docs.markedcopy_url'   => $url);
                   1207:     delete($env{'form.markcopy'});
                   1208: }
                   1209: 
                   1210: sub print_paste_buffer {
                   1211:     my ($r,$container) = @_;
                   1212:     return if (!defined($env{'docs.markedcopy_url'}));
                   1213: 
                   1214:     $r->print(<<ENDPASTE);
1.286     albertel 1215: <form name="pasteform" action="/adm/coursedocs" method="post"><p>
1.281     albertel 1216: ENDPASTE
                   1217:     $r->print('<input type="submit" name="pastemarked" value="'.&mt('Paste').'" /> ');
                   1218: 
                   1219:     my $type;
1.287     albertel 1220:     if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//} ) {
1.281     albertel 1221: 	$type = &mt('External Resource');
1.287     albertel 1222: 	$r->print($type.': '.
                   1223: 		  &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('.
                   1224: 		  &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')');
1.281     albertel 1225:     }  else {
                   1226: 	my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1];
                   1227: 	my $type = &Apache::loncommon::filedescription($extension);
                   1228: 	my $icon = '<img src="'.&Apache::loncommon::icon($extension).
1.286     albertel 1229: 	    '" alt="" class="LC_icon" />';
1.287     albertel 1230: 	$r->print($icon.$type.': '.  &parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'})));
1.281     albertel 1231:     }
                   1232:     if ($container eq 'page') {
1.286     albertel 1233: 	$r->print('
                   1234: 	<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />
                   1235: 	<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />
                   1236: ');
1.281     albertel 1237:     } else {
1.286     albertel 1238: 	$r->print('
                   1239:         <input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />
                   1240: ');
1.281     albertel 1241:     }
1.286     albertel 1242:     $r->print('</p></form>');
1.281     albertel 1243: }
                   1244: 
1.7       www      1245: sub editor {
1.281     albertel 1246:     my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$which)=@_;
1.10      www      1247:     my $errtext='';
                   1248:     my $fatal=0;
1.142     raeburn  1249:     my $container='sequence';
1.174     albertel 1250:     if ($env{'form.pagepath'}) {
1.142     raeburn  1251:         $container='page';
                   1252:     }
1.281     albertel 1253:     ($errtext,$fatal) = &mapread($coursenum,$coursedom,$folder.'.'.$container);
1.245     albertel 1254:     if ($#LONCAPA::map::order<1) {
                   1255: 	my $idx=&LONCAPA::map::getresidx();
1.178     www      1256: 	if ($idx<=0) { $idx=1; }
1.245     albertel 1257:        	$LONCAPA::map::order[0]=$idx;
                   1258:         $LONCAPA::map::resources[$idx]='';
1.17      www      1259:     }
1.281     albertel 1260:     
1.251     www      1261:     my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain)=&breadcrumbs($folder);
1.242     www      1262:     $r->print($breadcrumbtrail);
1.7       www      1263:     if ($fatal) {
1.283     albertel 1264: 	   $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.7       www      1265:     } else {
                   1266: # ------------------------------------------------------------ Process commands
1.121     www      1267: 
1.16      www      1268: # ---------------- if they are for this folder and user allowed to make changes
1.174     albertel 1269: 	if (($allowed) && ($env{'form.folder'} eq $folder)) {
1.123     www      1270: # set parameters and change order
1.247     www      1271:             &snapshotbefore();
                   1272: 	    if ($env{'form.changeparms'}) {
1.174     albertel 1273: 		my $idx=$env{'form.setparms'};
1.123     www      1274: # set parameters
1.258     www      1275: 		if ($env{'form.changeparms'} eq 'randompick') {
                   1276: 		    if ($env{'form.randpick_'.$idx}) {
                   1277: 			&LONCAPA::map::storeparameter($idx,'parameter_randompick',$env{'form.randpick_'.$idx},'int_pos');
                   1278: 			&remember_parms($idx,'randompick','set',$env{'form.randpick_'.$idx});
                   1279: 		    } else {
                   1280: 			&LONCAPA::map::delparameter($idx,'parameter_randompick');
                   1281: 			&remember_parms($idx,'randompick','del');
                   1282: 		    }
                   1283: 		}
                   1284: 		if ($env{'form.changeparms'} eq 'hiddenresource') {
                   1285: 		    if ($env{'form.hidprs_'.$idx}) {
                   1286: 			&LONCAPA::map::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno');
                   1287: 			&remember_parms($idx,'hiddenresource','set',$env{'form.hidprs_'.$idx});
                   1288: 		    } else {
                   1289: 			&LONCAPA::map::delparameter($idx,'parameter_hiddenresource');
                   1290: 			&remember_parms($idx,'hiddenresource','del');
                   1291: 		    }
                   1292: 		}
                   1293: 		if ($env{'form.changeparms'} eq 'encrypturl') {
                   1294: 		    if ($env{'form.encprs_'.$idx}) {
                   1295: 			&LONCAPA::map::storeparameter($idx,'parameter_encrypturl','yes','string_yesno');
                   1296: 			&remember_parms($idx,'encrypturl','set',$env{'form.encprs_'.$idx});
                   1297: 		    } else {
                   1298: 			&LONCAPA::map::delparameter($idx,'parameter_encrypturl');
                   1299: 			&remember_parms($idx,'encrypturl','del');
                   1300: 		    }
1.121     www      1301: 		}
1.250     www      1302: # store the changed version
                   1303: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   1304: 		if ($fatal) {
1.283     albertel 1305: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.250     www      1306: 		    return;
                   1307: 		}
1.247     www      1308: 	    }
1.121     www      1309: 
1.247     www      1310: 	    if ($env{'form.newpos'}) {
1.123     www      1311: # change order
1.247     www      1312: 		my $newpos=$env{'form.newpos'}-1;
                   1313: 		my $currentpos=$env{'form.currentpos'}-1;
                   1314: 		my $i;
                   1315: 		my @neworder=();
                   1316: 		if ($newpos>$currentpos) {
1.125     www      1317: # moving stuff up
1.247     www      1318: 		    for ($i=0;$i<$currentpos;$i++) {
                   1319: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1320: 		    }
                   1321: 		    for ($i=$currentpos;$i<$newpos;$i++) {
                   1322: 			$neworder[$i]=$LONCAPA::map::order[$i+1];
                   1323: 		    }
                   1324: 		    $neworder[$newpos]=$LONCAPA::map::order[$currentpos];
                   1325: 		    for ($i=$newpos+1;$i<=$#LONCAPA::map::order;$i++) {
                   1326: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1327: 		    }
                   1328: 		} else {
1.125     www      1329: # moving stuff down
1.247     www      1330: 		    for ($i=0;$i<$newpos;$i++) {
                   1331: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1332: 		    }
                   1333: 		    $neworder[$newpos]=$LONCAPA::map::order[$currentpos];
                   1334: 		    for ($i=$newpos+1;$i<$currentpos+1;$i++) {
                   1335: 			$neworder[$i]=$LONCAPA::map::order[$i-1];
                   1336: 		    }
                   1337: 		    for ($i=$currentpos+1;$i<=$#LONCAPA::map::order;$i++) {
                   1338: 			$neworder[$i]=$LONCAPA::map::order[$i];
1.125     www      1339: 		    }
1.124     www      1340: 		}
1.247     www      1341: 		@LONCAPA::map::order=@neworder;
1.124     www      1342: # store the changed version
1.142     raeburn  1343: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
1.124     www      1344: 		if ($fatal) {
1.283     albertel 1345: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.124     www      1346: 		    return;
1.123     www      1347: 		}
1.247     www      1348: 	    }
1.281     albertel 1349: 	    
1.174     albertel 1350: 	    if ($env{'form.pastemarked'}) {
1.168     www      1351: # paste resource to end of list
1.287     albertel 1352:                 my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'});
                   1353: 		my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'});
1.168     www      1354: # Maps need to be copied first
                   1355: 		if (($url=~/\.(page|sequence)$/) || ($url=~/^\/uploaded\//)) {
                   1356: 		    $title=&mt('Copy of').' '.$title;
                   1357:                     my $newid=$$.time;
                   1358: 		    $url=~/^(.+)\.(\w+)$/;
                   1359: 		    my $newurl=$1.$newid.'.'.$2;
                   1360: 		    my $storefn=$newurl;
1.264     albertel 1361:                     $storefn=~s{^/\w+/$match_domain/$match_username/}{};
1.244     albertel 1362: 		    &Apache::lonclonecourse::writefile
1.174     albertel 1363: 			($env{'request.course.id'},$storefn,
1.168     www      1364: 			 &Apache::lonnet::getfile($url));
                   1365: 		    $url=$newurl;
                   1366: 		}
1.270     albertel 1367: 		$title = &LONCAPA::map::qtunescape($title);
1.168     www      1368: 		my $ext='false';
1.287     albertel 1369: 		if ($url=~m{^http(|s)://}) { $ext='true'; }
1.270     albertel 1370: 		$url   = &LONCAPA::map::qtunescape($url);
1.168     www      1371: # Now insert the URL at the bottom
1.245     albertel 1372:                 my $newidx=&LONCAPA::map::getresidx($url);
                   1373: 		$LONCAPA::map::resources[$newidx]=
1.168     www      1374: 		    $title.':'.$url.':'.$ext.':normal:res';
1.245     albertel 1375: 		$LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
1.168     www      1376: # Store the result
                   1377: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   1378: 		if ($fatal) {
1.283     albertel 1379: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.168     www      1380: 		    return;
                   1381: 		}
1.123     www      1382: 
1.168     www      1383: 	    }
1.188     raeburn  1384:             $r->print($upload_output);
1.174     albertel 1385: 	    if ($env{'form.cmd'}) {
                   1386:                 my ($cmd,$idx)=split(/\_/,$env{'form.cmd'});
1.10      www      1387:                 if ($cmd eq 'del') {
1.245     albertel 1388: 		    my (undef,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
1.187     www      1389: 		    if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
1.206     albertel 1390: 			($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) {
1.187     www      1391: 			&Apache::lonnet::removeuploadedurl($url);
                   1392: 		    } else {
1.245     albertel 1393: 			&LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
1.128     albertel 1394: 		    }
1.245     albertel 1395: 		    for (my $i=$idx;$i<$#LONCAPA::map::order;$i++) {
                   1396:                         $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
1.10      www      1397:                     }
1.245     albertel 1398:                     $#LONCAPA::map::order--;
1.171     www      1399:                 } elsif ($cmd eq 'cut') {
1.245     albertel 1400: 		    my (undef,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
                   1401: 		    &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
                   1402: 		    for (my $i=$idx;$i<$#LONCAPA::map::order;$i++) {
                   1403:                         $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
1.171     www      1404:                     }
1.245     albertel 1405:                     $#LONCAPA::map::order--;
1.10      www      1406:                 } elsif ($cmd eq 'up') {
1.245     albertel 1407: 		  if (($idx) && (defined($LONCAPA::map::order[$idx-1]))) {
                   1408:                     my $i=$LONCAPA::map::order[$idx-1];
                   1409:                     $LONCAPA::map::order[$idx-1] = $LONCAPA::map::order[$idx];
                   1410:                     $LONCAPA::map::order[$idx] = $i;
1.38      www      1411: 		   }
1.10      www      1412:                 } elsif ($cmd eq 'down') {
1.245     albertel 1413: 		   if (defined($LONCAPA::map::order[$idx+1])) {
                   1414:                     my $i=$LONCAPA::map::order[$idx+1];
                   1415:                     $LONCAPA::map::order[$idx+1] = $LONCAPA::map::order[$idx];
                   1416:                     $LONCAPA::map::order[$idx] = $i;
1.38      www      1417: 		   }
1.36      www      1418:                 } elsif ($cmd eq 'rename') {
1.245     albertel 1419:                     my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
1.36      www      1420:                     my ($rtitle,@rrest)=split(/\:/,
1.245     albertel 1421:                        $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
1.270     albertel 1422:                     my $comment=$env{'form.title'};
                   1423:                     $comment = &LONCAPA::map::qtunescape($comment);
1.144     albertel 1424: 		    if ($comment=~/\S/) {
1.245     albertel 1425: 			$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]=
                   1426: 			    $comment.':'.join(':',@rrest);
1.144     albertel 1427: 		    }
1.238     www      1428: # Devalidate title cache
1.270     albertel 1429:                     my $renamed_url=&LONCAPA::map::qtescape($rrest[0]);
1.240     www      1430: 		    &Apache::lonnet::devalidate_title_cache($renamed_url);
1.10      www      1431:                 }
                   1432: # Store the changed version
1.104     albertel 1433: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.142     raeburn  1434: 					    $folder.'.'.$container);
1.104     albertel 1435: 		if ($fatal) {
1.283     albertel 1436: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.104     albertel 1437: 		    return;
                   1438: 		}
1.8       www      1439:             }
1.11      www      1440: # Group import/search
1.174     albertel 1441: 	    if ($env{'form.importdetail'}) {
1.73      bowersj2 1442: 		my @imports;
1.174     albertel 1443: 		foreach (split(/\&/,$env{'form.importdetail'})) {
1.73      bowersj2 1444: 		    if (defined($_)) {
1.287     albertel 1445: 			my ($name,$url,$residx)=
                   1446: 			    map {&unescape($_)} split(/\=/,$_);
                   1447: 			push(@imports, [$name, $url, $residx]);
1.73      bowersj2 1448: 		    }
                   1449: 		}
1.11      www      1450: # Store the changed version
1.249     www      1451: 		($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder,
1.142     raeburn  1452: 					       $container,'londocs',@imports);
1.104     albertel 1453: 		if ($fatal) {
1.283     albertel 1454: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.104     albertel 1455: 		    return;
                   1456: 		}
1.11      www      1457:             }
1.53      www      1458: # Loading a complete map
1.223     www      1459: 	   if ($env{'form.loadmap'}) {
                   1460:                if ($env{'form.importmap'}=~/\w/) {
                   1461: 	          foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
                   1462: 		      my ($title,$url,$ext,$type)=split(/\:/,$_);
1.245     albertel 1463:                       my $idx=&LONCAPA::map::getresidx($url);
                   1464:                       $LONCAPA::map::resources[$idx]=$_;
                   1465:                       $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx;
1.223     www      1466: 	          }
1.53      www      1467: # Store the changed version
1.223     www      1468:   	          ($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.142     raeburn  1469: 					   $folder.'.'.$container);
1.223     www      1470: 	          if ($fatal) {
1.283     albertel 1471: 		      $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.223     www      1472: 		      return;
                   1473: 	          }
                   1474:                } else {
1.283     albertel 1475: 		    $r->print('<p><span class="LC_error">'.&mt('No map selected.').'</span></p>');
                   1476: 
1.223     www      1477:                }
1.53      www      1478:            }
1.251     www      1479:            &log_differences($plain);
1.281     albertel 1480: 	}
1.16      www      1481: # ---------------------------------------------------------------- End commands
1.7       www      1482: # ---------------------------------------------------------------- Print screen
1.10      www      1483:         my $idx=0;
1.148     www      1484: 	my $shown=0;
1.242     www      1485:         if (($ishidden) || ($isencrypted) || ($randompick>=0)) {
                   1486:            $r->print('<p>'.&mt('Parameters').':<ul>'.
                   1487:                      ($randompick>=0?'<li>'.&mt('randomly pick [_1] resources',$randompick).'</li>':'').
                   1488:                      ($ishidden?'<li>'.&mt('contents hidden').'</li>':'').
                   1489:                      ($isencrypted?'<li>'.&mt('URLs hidden').'</li>':'').
                   1490:                      '</ul></p>');
                   1491:         }                                                                                                     
                   1492:         if ($randompick>=0) {
                   1493:            $r->print('<p>'.&mt('Caution: this folder is set to randomly pick a subset of resources. Adding or removing resources from this folder will change the set of resources that the students see, resulting in spurious or missing credit for completed problems, not limited to ones you modify. Do not modify the contents of this folder if it is in active student use.').'</p>');
                   1494:         }
1.285     albertel 1495:         $r->print('<table class="LC_docs_editor">');
1.278     albertel 1496:         foreach my $res (@LONCAPA::map::order) {
                   1497:            my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
1.246     raeburn  1498: 	   $name=&LONCAPA::map::qtescape($name);
1.271     albertel 1499: 	   $url=&LONCAPA::map::qtescape($url);
1.10      www      1500:            unless ($name) {  $name=(split(/\//,$url))[-1]; }
1.148     www      1501:            unless ($name) { $idx++; next; }
1.278     albertel 1502:            $r->print(&entryline($idx,$name,$url,$folder,$allowed,$res,
                   1503: 				$coursenum));
1.10      www      1504:            $idx++;
1.148     www      1505: 	   $shown++;
1.10      www      1506:         }
1.148     www      1507: 	unless ($shown) {
1.131     www      1508: 	    $r->print('<tr><td>'.&mt('Currently no documents.').'</td></tr>');
                   1509: 	}
1.168     www      1510:         $r->print("\n</table>\n");
1.278     albertel 1511: 
1.281     albertel 1512: 	&print_paste_buffer($r,$container);
                   1513: 
1.7       www      1514:     }
                   1515: }
1.1       www      1516: 
1.188     raeburn  1517: sub process_file_upload {
1.194     raeburn  1518:     my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
1.188     raeburn  1519: # upload a file, if present
                   1520:     my $parseaction;
1.190     albertel 1521:    if ($env{'form.parserflag'}) {
1.188     raeburn  1522:         $parseaction = 'parse';
                   1523:     }
                   1524:     my $phase_status;
                   1525:     my $folder=$env{'form.folder'};
1.194     raeburn  1526:     if ($folder eq '') {
1.188     raeburn  1527:         $folder='default';
                   1528:     }
1.194     raeburn  1529:     if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
1.188     raeburn  1530:         my $errtext='';
                   1531:         my $fatal=0;
                   1532:         my $container='sequence';
                   1533:         if ($env{'form.pagepath'}) {
                   1534:             $container='page';
                   1535:         }
                   1536:         ($errtext,$fatal)=
                   1537:               &mapread($coursenum,$coursedom,$folder.'.'.$container);
1.245     albertel 1538:         if ($#LONCAPA::map::order<1) {
                   1539:             $LONCAPA::map::order[0]=1;
                   1540:             $LONCAPA::map::resources[1]='';
1.188     raeburn  1541:         }
                   1542:         if ($fatal) {
                   1543:             return 'failed';
                   1544:         }
                   1545:         my $destination = 'docs/';
1.194     raeburn  1546:         if ($folder =~ /^supplemental/) {
                   1547:             $destination = 'supplemental/';
                   1548:         }
                   1549:         if (($folder eq 'default') || ($folder eq 'supplemental')) {
1.188     raeburn  1550:             $destination .= 'default/';
1.194     raeburn  1551:         } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
                   1552:             $destination .=  $2.'/';
1.188     raeburn  1553:         }
                   1554: # this is for a course, not a user, so set coursedoc flag
                   1555: # probably the only place in the system where this should be "1"
1.245     albertel 1556:         my $newidx=&LONCAPA::map::getresidx();
1.188     raeburn  1557:         $destination .= $newidx;
1.190     albertel 1558:         my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination,
                   1559: 						$parseaction,$allfiles,
                   1560: 						$codebase);
1.188     raeburn  1561:         my $ext='false';
1.287     albertel 1562:         if ($url=~m{^http://}) { $ext='true'; }
1.270     albertel 1563: 	$url     = &LONCAPA::map::qtunescape($url);
1.188     raeburn  1564:         my $comment=$env{'form.comment'};
1.270     albertel 1565: 	$comment = &LONCAPA::map::qtunescape($comment);
1.188     raeburn  1566:         if ($folder=~/^supplemental/) {
                   1567:               $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                   1568:                   $env{'user.domain'}.'___&&&___'.$comment;
                   1569:         }
                   1570: 
1.245     albertel 1571:         $LONCAPA::map::resources[$newidx]=
                   1572: 	    $comment.':'.$url.':'.$ext.':normal:res';
                   1573:         $LONCAPA::map::order[$#LONCAPA::map::order+1]= $newidx;
1.190     albertel 1574:         ($errtext,$fatal)=&storemap($coursenum,$coursedom,
                   1575: 				    $folder.'.'.$container);
1.188     raeburn  1576:         if ($fatal) {
1.283     albertel 1577:             $$upload_output .= '<p><span class="LC_error">'.$errtext.'</span></p>';
1.188     raeburn  1578:             return 'failed';
                   1579:         } else {
                   1580:             if ($parseaction eq 'parse') {
1.190     albertel 1581:                 my $total_embedded = keys(%{$allfiles});
1.188     raeburn  1582:                 if ($total_embedded > 0) {
                   1583:                     my $num = 0;
1.269     albertel 1584: 		    my $state = '
1.282     albertel 1585:    <input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />
1.269     albertel 1586:    <input type="hidden" name="cmd" value="upload_embedded" />
1.188     raeburn  1587:    <input type="hidden" name="newidx" value="'.$newidx.'" />
1.228     www      1588:    <input type="hidden" name="primaryurl" value="'.&escape($url).'" />
1.188     raeburn  1589:    <input type="hidden" name="phasetwo" value="'.$total_embedded.'" />';
1.269     albertel 1590: 		    $phase_status = 'phasetwo';
                   1591: 
                   1592:                     $$upload_output .= 
                   1593: 			'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br />'.
                   1594: 			&ask_for_embedded_content('/adm/coursedocs',
                   1595: 						  $state,$allfiles,$codebase);
1.188     raeburn  1596:                 } else {
                   1597:                     $$upload_output .= 'No embedded items identified<br />';
                   1598:                 }
                   1599:             }
                   1600:         }
                   1601:     }
                   1602:     return $phase_status;
                   1603: }
                   1604: 
1.269     albertel 1605: sub ask_for_embedded_content {
1.271     albertel 1606:     my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
1.269     albertel 1607:     my $upload_output = '
                   1608:    <form name="upload_embedded" action="'.$actionurl.'"
                   1609:                   method="post" enctype="multipart/form-data">';
                   1610:     $upload_output .= $state;
1.271     albertel 1611:     $upload_output .= '<b>Upload embedded files</b>:<br />'.
                   1612: 	&Apache::loncommon::start_data_table();
1.269     albertel 1613: 
                   1614:     my $num = 0;
1.276     albertel 1615:     foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) {
1.271     albertel 1616: 	$upload_output .= &Apache::loncommon::start_data_table_row().
                   1617: 	    '<td>'.$embed_file.'</td><td>';
1.274     albertel 1618: 	if ($args->{'ignore_remote_references'}
                   1619: 	    && $embed_file =~ m{^\w+://}) {
                   1620: 	    $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
                   1621: 	} elsif ($args->{'error_on_invalid_names'}
1.271     albertel 1622: 	    && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
                   1623: 	    
                   1624: 	    $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';
1.274     albertel 1625: 	    
1.271     albertel 1626: 	} else {
1.274     albertel 1627: 
1.271     albertel 1628: 	    $upload_output .='
1.269     albertel 1629:            <input name="embedded_item_'.$num.'" type="file" value="bob" />
                   1630:            <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
1.271     albertel 1631: 	    my $attrib = join(':',@{$$allfiles{$embed_file}});
                   1632: 	    $upload_output .=
1.269     albertel 1633: 		"\n\t\t".
1.271     albertel 1634: 		'<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
                   1635: 		$attrib.'" />';
                   1636: 	    if (exists($$codebase{$embed_file})) {
                   1637: 		$upload_output .= 
                   1638: 		    "\n\t\t".
                   1639: 		    '<input name="codebase_'.$num.'" type="hidden" value="'.
                   1640: 		    &escape($$codebase{$embed_file}).'" />';
                   1641: 	    }
1.269     albertel 1642: 	}
1.271     albertel 1643: 	$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();
1.269     albertel 1644: 	$num++;
                   1645:     }
1.271     albertel 1646:     $upload_output .= &Apache::loncommon::end_data_table().'<br />
1.269     albertel 1647:    <input type ="hidden" name="number_embedded_items" value="'.$num.'" />
1.275     albertel 1648:    <input type ="submit" value="'.&mt('Upload Listed Files').'" />
                   1649:    '.&mt('(only files for which a location has been provided will be uploaded)').'
1.269     albertel 1650:    </form>';
                   1651:     return $upload_output;
                   1652: }
                   1653: 
1.188     raeburn  1654: sub process_secondary_uploads {
                   1655:     my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
                   1656:     my $folder=$env{'form.folder'};
                   1657:     my $destination = 'docs/';
1.195     raeburn  1658:     if ($folder =~ /^supplemental/) {
                   1659:         $destination = 'supplemental/';
                   1660:     }
                   1661:     if (($folder eq 'default') || ($folder eq 'supplemental')) {
1.188     raeburn  1662:         $destination .= 'default/';
1.195     raeburn  1663:     } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
1.217     raeburn  1664:         $destination .=  $2.'/';
1.188     raeburn  1665:     }
                   1666:     $destination .= $newidx;
                   1667:     my ($url,$filename);
                   1668:     $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination);
1.265     albertel 1669:     ($filename) = ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/\Q$destination\E/(.+)$});
1.188     raeburn  1670:     return $filename;
                   1671: }
                   1672: 
1.281     albertel 1673: sub is_supplemental_title {
                   1674:     my ($title) = @_;
                   1675:     return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
                   1676: }
                   1677: 
                   1678: sub parse_supplemental_title {
                   1679:     my ($title) = @_;
                   1680: 
                   1681:     my ($foldertitle,$renametitle);
                   1682:     if ($title =~ /&amp;&amp;&amp;/) {
                   1683: 	$title = &HTML::Entites::decode($title);
                   1684:     }
                   1685:  if ($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/) {
                   1686: 	$renametitle=$4;
                   1687: 	my ($time,$uname,$udom) = ($1,$2,$3);
                   1688: 	$foldertitle=&Apache::lontexconvert::msgtexconverted($4);
                   1689: 	my $name =  &Apache::loncommon::plainname($uname,$udom);
                   1690: 	$name = &HTML::Entities::encode($name,'"<>&\'');
                   1691: 	$title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.
                   1692: 	    $name.': <br />'.$foldertitle;
                   1693:     }
                   1694:     if (wantarray) {
                   1695: 	return ($title,$foldertitle,$renametitle);
                   1696:     } 
                   1697:     return $title;
                   1698: }
                   1699: 
1.8       www      1700: # --------------------------------------------------------------- An entry line
                   1701: 
                   1702: sub entryline {
1.112     raeburn  1703:     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_;
1.281     albertel 1704: 
                   1705:     my ($foldertitle,$pagetitle,$renametitle);
                   1706:     if (&is_supplemental_title($title)) {
                   1707: 	($title,$foldertitle,$renametitle) = &parse_supplemental_title($title);
                   1708: 	$pagetitle = $foldertitle;
                   1709:     } else {
                   1710: 	$title=&HTML::Entities::encode($title,'"<>&\'');
                   1711: 	$renametitle=$title;
                   1712: 	$foldertitle=$title;
                   1713: 	$pagetitle=$title;
                   1714:     }
                   1715: 
1.245     albertel 1716:     my $orderidx=$LONCAPA::map::order[$index];
1.281     albertel 1717:     
                   1718: 
1.222     albertel 1719:     $renametitle=~s/\\/\\\\/g;
1.38      www      1720:     $renametitle=~s/\&quot\;/\\\"/g;
1.286     albertel 1721:     $renametitle=~s/ /%20/g;
1.8       www      1722:     my $line='<tr>';
1.286     albertel 1723:     my ($form_start,$form_end);
1.8       www      1724: # Edit commands
1.142     raeburn  1725:     my $container;
1.280     albertel 1726:     my ($container, $type, $esc_path, $path, $symb);
1.174     albertel 1727:     if ($env{'form.folderpath'}) {
1.280     albertel 1728: 	$type = 'folder';
1.142     raeburn  1729:         $container = 'sequence';
1.282     albertel 1730: 	$esc_path=&escape($env{'form.folderpath'});
                   1731: 	$path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.174     albertel 1732: 	# $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"');
1.120     www      1733:     }
1.174     albertel 1734:     if ($env{'form.pagepath'}) {
1.280     albertel 1735:         $type = $container = 'page';
                   1736:         $esc_path=&escape($path = $env{'form.pagepath'});
1.282     albertel 1737: 	$path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"');
1.280     albertel 1738:         $symb=&escape($env{'form.pagesymb'});
1.142     raeburn  1739:     }
1.168     www      1740:     my $cpinfo='';
1.109     albertel 1741:     if ($allowed) {
1.123     www      1742: 	my $incindex=$index+1;
                   1743: 	my $selectbox='';
1.168     www      1744: 	if (($folder!~/^supplemental/) &&
1.245     albertel 1745: 	    ($#LONCAPA::map::order>0) && 
1.168     www      1746: 	    ((split(/\:/,
1.245     albertel 1747: 	     $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1] 
1.168     www      1748: 	     ne '') && 
                   1749: 	    ((split(/\:/,
1.245     albertel 1750: 	     $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1] 
1.168     www      1751: 	     ne '')) {
1.123     www      1752: 	    $selectbox=
1.124     www      1753: 		'<input type="hidden" name="currentpos" value="'.$incindex.'" />'.
1.123     www      1754: 		'<select name="newpos" onChange="this.form.submit()">';
1.245     albertel 1755: 	    for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) {
1.123     www      1756: 		if ($i==$incindex) {
                   1757: 		    $selectbox.='<option value="" selected="1">('.$i.')</option>';
                   1758: 		} else {
                   1759: 		    $selectbox.='<option value="'.$i.'">'.$i.'</option>';
                   1760: 		}
                   1761: 	    }
                   1762: 	    $selectbox.='</select>';
                   1763: 	}
1.119     www      1764: 	my %lt=&Apache::lonlocal::texthash(
                   1765:                 'up' => 'Move Up',
1.109     albertel 1766: 		'dw' => 'Move Down',
                   1767: 		'rm' => 'Remove',
1.171     www      1768:                 'ct' => 'Cut',
1.168     www      1769: 		'rn' => 'Rename',
                   1770: 		'cp' => 'Copy');
1.211     www      1771: 	my $nocopy=0;
1.268     www      1772:         my $nocut=0;
1.211     www      1773:         if ($url=~/\.(page|sequence)$/) {
                   1774: 	    foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url))) {
                   1775: 		my ($title,$url,$ext,$type)=split(/\:/,$_);
                   1776: 		if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) {
                   1777: 		    $nocopy=1;
                   1778: 		    last;
                   1779: 		}
                   1780: 	    }
                   1781: 	}
1.268     www      1782:         if ($url=~/^\/res\/lib\/templates\//) { 
                   1783:            $nocopy=1; 
                   1784:            $nocut=1;
                   1785:         }
1.211     www      1786:         my $copylink='&nbsp;';
1.267     www      1787:         my $cutlink='&nbsp;';
1.280     albertel 1788: 	
                   1789: 	if (!$nocopy) {
                   1790: 	    $copylink=(<<ENDCOPY);
1.284     albertel 1791: <a href='javascript:markcopy("$esc_path","$index","$renametitle","$container","$symb","$folder");' class="LC_docs_copy">$lt{'cp'}</a>
1.211     www      1792: ENDCOPY
1.280     albertel 1793:         }
                   1794: 	if (!$nocut) {
                   1795: 	    $cutlink=(<<ENDCUT);
1.284     albertel 1796: <a href='javascript:cutres("$esc_path","$index","$renametitle","$container","$symb","$folder");' class="LC_docs_cut">$lt{'ct'}</a>
1.267     www      1797: ENDCUT
1.280     albertel 1798:         }
1.286     albertel 1799: 	$form_start = (<<END);
                   1800:    <form  action="/adm/coursedocs" method="post">
1.280     albertel 1801:    <input type="hidden" name="${type}path" value="$path" />
                   1802:    <input type="hidden" name="${type}symb" value="$symb" />
                   1803:    <input type="hidden" name="setparms" value="$orderidx" />
                   1804:    <input type="hidden" name="changeparms" value="0" />
1.286     albertel 1805: END
                   1806:         $form_end = '</form>';
                   1807: 	$line.=(<<END);
1.280     albertel 1808: <td>
1.285     albertel 1809:    <table class="LC_docs_entry_move">
1.280     albertel 1810:       <tr>
1.285     albertel 1811:          <td>
1.282     albertel 1812:             <a href='/adm/coursedocs?cmd=up_$index&amp;${type}path=$esc_path&amp;${type}symb=$symb$cpinfo'><img src="${iconpath}move_up.gif" alt='$lt{'up'}' class="LC_icon" /></a>
1.280     albertel 1813:          </td>
                   1814:       </tr>
                   1815:       <tr>
1.285     albertel 1816:         <td>
1.282     albertel 1817:            <a href='/adm/coursedocs?cmd=down_$index&amp;${type}path=$esc_path&amp;${type}symb=$symb$cpinfo'><img src="${iconpath}move_down.gif" alt='$lt{'dw'}' class="LC_icon" /></a>
1.280     albertel 1818:         </td>
                   1819:       </tr>
                   1820:     </table>
                   1821: </td>
                   1822: <td>
1.286     albertel 1823:    $form_start
1.280     albertel 1824:    $selectbox
1.286     albertel 1825:    $form_end
1.280     albertel 1826: </td>
1.285     albertel 1827: <td class="LC_docs_entry_commands">
1.284     albertel 1828:    <a href='javascript:removeres("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_remove">$lt{'rm'}</a>
1.267     www      1829: $cutlink
1.284     albertel 1830:    <a href='javascript:changename("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_rename">$lt{'rn'}</a>
1.211     www      1831: $copylink
1.280     albertel 1832: </td>
1.142     raeburn  1833: END
1.280     albertel 1834: 
1.8       www      1835:     }
1.16      www      1836: # Figure out what kind of a resource this is
                   1837:     my ($extension)=($url=~/\.(\w+)$/);
                   1838:     my $uploaded=($url=~/^\/*uploaded\//);
1.97      albertel 1839:     my $icon=&Apache::loncommon::icon($url);
1.17      www      1840:     my $isfolder=0;
1.142     raeburn  1841:     my $ispage=0;
1.114     albertel 1842:     my $folderarg;
1.142     raeburn  1843:     my $pagearg;
                   1844:     my $pagefile;
1.16      www      1845:     if ($uploaded) {
1.135     albertel 1846: 	if ($extension eq 'sequence') {
                   1847: 	    $icon=$iconpath.'/folder_closed.gif';
1.264     albertel 1848: 	    $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
1.135     albertel 1849: 	    $url='/adm/coursedocs?';
                   1850: 	    $folderarg=$1;
                   1851: 	    $isfolder=1;
1.142     raeburn  1852:         } elsif ($extension eq 'page') {
                   1853:             $icon=$iconpath.'/page.gif';
1.264     albertel 1854:             $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
1.142     raeburn  1855:             $pagearg=$1;
                   1856:             $url='/adm/coursedocs?';
                   1857:             $ispage=1;
1.135     albertel 1858: 	} else {
                   1859: 	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
                   1860: 	}
1.16      www      1861:     }
1.287     albertel 1862:     
                   1863:     my $orig_url = $url;
                   1864:     my $external = ($url=~s{^http(|s)(&colon;|:)//}{/adm/wrapper/ext/});
1.142     raeburn  1865:     if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) {
1.113     albertel 1866: 	my $symb=&Apache::lonnet::symbclean(
1.50      www      1867:           &Apache::lonnet::declutter('uploaded/'.
1.174     albertel 1868:            $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
                   1869:            $env{'course.'.$env{'request.course.id'}.'.num'}.'/'.$folder.
1.50      www      1870:            '.sequence').
                   1871:            '___'.$residx.'___'.
1.113     albertel 1872: 	   &Apache::lonnet::declutter($url));
                   1873: 	(undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
                   1874: 	$url=&Apache::lonnet::clutter($url);
1.127     albertel 1875: 	if ($url=~/^\/*uploaded\//) {
                   1876: 	    $url=~/\.(\w+)$/;
                   1877: 	    my $embstyle=&Apache::loncommon::fileembstyle($1);
                   1878: 	    if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                   1879: 		$url='/adm/wrapper'.$url;
                   1880: 	    } elsif ($embstyle eq 'ssi') {
                   1881: 		#do nothing with these
                   1882: 	    } elsif ($url!~/\.(sequence|page)$/) {
                   1883: 		$url='/adm/coursedocs/showdoc'.$url;
                   1884: 	    }
1.145     albertel 1885: 	} elsif ($url=~m|^/ext/|) { 
                   1886: 	    $url='/adm/wrapper'.$url;
1.287     albertel 1887: 	    $external = 1;
1.127     albertel 1888: 	}
1.241     www      1889:         if (&Apache::lonnet::symbverify($symb,$url)) {
                   1890: 	    $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
                   1891:         } else {
                   1892:             $url='';
                   1893:         }
1.152     albertel 1894: 	if ($container eq 'page') {
1.174     albertel 1895: 	    my $symb=$env{'form.pagesymb'};
1.152     albertel 1896: 	    	    
                   1897: 	    $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
1.228     www      1898: 	    $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
1.152     albertel 1899: 	}
1.50      www      1900:     }
1.120     www      1901:     my $parameterset='&nbsp;';
1.216     albertel 1902:     if ($isfolder || $extension eq 'sequence') {
1.228     www      1903: 	my $foldername=&escape($foldertitle);
1.174     albertel 1904: 	my $folderpath=$env{'form.folderpath'};
1.114     albertel 1905: 	if ($folderpath) { $folderpath.='&' };
1.242     www      1906: # Append randompick number, hidden, and encrypted with ":" to foldername, 
                   1907: # so it gets transferred between levels
1.245     albertel 1908: 	$folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx,
1.242     www      1909:                                               'parameter_randompick'))[0]
1.245     albertel 1910:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
1.242     www      1911:                                               'parameter_hiddenresource'))[0]=~/^yes$/i)
1.245     albertel 1912:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
1.242     www      1913:                                               'parameter_encrypturl'))[0]=~/^yes$/i);
1.228     www      1914: 	$url.='folderpath='.&escape($folderpath).$cpinfo;
1.147     matthew  1915: 	$parameterset='<label>'.&mt('Randomly Pick: ').
1.258     www      1916: 	    '<input type="text" size="4" onChange="this.form.changeparms.value='."'randompick'".';this.form.submit()" name="randpick_'.$orderidx.'" value="'.
1.245     albertel 1917: 	    (&LONCAPA::map::getparameter($orderidx,
1.147     matthew  1918:                                               'parameter_randompick'))[0].
1.165     www      1919:                                               '" />'.
1.285     albertel 1920: '<a href="javascript:void(0)">'.&mt('Save').'</a></label>';
1.147     matthew  1921:        
1.114     albertel 1922:     }
1.142     raeburn  1923:     if ($ispage) {
1.228     www      1924:         my $pagename=&escape($pagetitle);
1.142     raeburn  1925:         my $pagepath;
1.174     albertel 1926:         my $folderpath=$env{'form.folderpath'};
1.142     raeburn  1927:         if ($folderpath) { $pagepath = $folderpath.'&' };
                   1928:         $pagepath.=$pagearg.'&'.$pagename;
1.174     albertel 1929: 	my $symb=$env{'form.pagesymb'};
1.152     albertel 1930: 	if (!$symb) {
                   1931: 	    my $path='uploaded/'.
1.174     albertel 1932: 		$env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
                   1933: 		$env{'course.'.$env{'request.course.id'}.'.num'}.'/';
1.152     albertel 1934: 	    $symb=&Apache::lonnet::encode_symb($path.$folder.'.sequence',
                   1935: 					       $residx,
                   1936: 					       $path.$pagearg.'.page');
                   1937: 	}
1.228     www      1938: 	$url.='pagepath='.&escape($pagepath).
1.282     albertel 1939: 	    '&amp;pagesymb='.&escape($symb).$cpinfo;
1.142     raeburn  1940:     }
1.287     albertel 1941:     if ($external) {
                   1942: 	my $form = ($folder =~ /^default/)? 'newext' : 'supnewext';
                   1943: 	$external = '&nbsp;<a class="LC_docs_ext_edit" href="javascript:edittext(\''.$form.'\',\''.$residx.'\',\''.&escape($title).'\',\''.&escape($orig_url).'\');" >'.&mt('Edit').'</a>';
                   1944:     } else {
                   1945: 	undef($external);
                   1946:     }
1.285     albertel 1947:     $line.='
                   1948:   <td class="LC_docs_entry_icon">
1.287     albertel 1949:     '.($url?'<a href="'.$url.'">':'').'<img src="'.$icon.'" alt="" class="LC_icon" />'.($url?'</a>':'').'
1.285     albertel 1950:   </td>
                   1951:   <td class="LC_docs_entry_title">
1.287     albertel 1952:     '.($url?"<a href=\"$url\">":'').$title.($url?'</a>':' <span class="LC_docs_reinit_warn">'.&mt('(re-initialize course to access)').'</span>').$external."
1.285     albertel 1953:   </td>";
1.120     www      1954:     if (($allowed) && ($folder!~/^supplemental/)) {
                   1955:  	my %lt=&Apache::lonlocal::texthash(
                   1956:  			      'hd' => 'Hidden',
1.165     www      1957:  			      'ec' => 'URL hidden');
1.122     www      1958: 	my $enctext=
1.245     albertel 1959: 	    ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':'');
1.122     www      1960: 	my $hidtext=
1.245     albertel 1961: 	    ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':'');
1.120     www      1962: 	$line.=(<<ENDPARMS);
1.285     albertel 1963:   <td class="LC_docs_entry_parameter">
1.286     albertel 1964:     $form_start
1.285     albertel 1965:     <label><input type="checkbox" name="hidprs_$orderidx" onClick="this.form.changeparms.value='hiddenresource';this.form.submit()" $hidtext /> $lt{'hd'}</label>
1.286     albertel 1966:     $form_end
1.285     albertel 1967:   </td>
                   1968:   <td class="LC_docs_entry_parameter">
1.286     albertel 1969:     $form_start
1.285     albertel 1970:     <label><input type="checkbox" name="encprs_$orderidx" onClick="this.form.changeparms.value='encrypturl';this.form.submit()" $enctext /> $lt{'ec'}</label>
1.286     albertel 1971:     $form_end
1.285     albertel 1972:   </td>
1.286     albertel 1973:   <td class="LC_docs_entry_parameter">$form_start $parameterset $form_end</td>
1.120     www      1974: ENDPARMS
1.119     www      1975:     }
1.286     albertel 1976:     $line.="</tr>";
1.8       www      1977:     return $line;
                   1978: }
                   1979: 
1.27      www      1980: # ---------------------------------------------------------------- tie the hash
                   1981: 
                   1982: sub tiehash {
1.136     albertel 1983:     my ($mode)=@_;
1.27      www      1984:     $hashtied=0;
1.174     albertel 1985:     if ($env{'request.course.fn'}) {
1.136     albertel 1986: 	if ($mode eq 'write') {
1.174     albertel 1987: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136     albertel 1988: 		    &GDBM_WRCREAT(),0640)) {
                   1989:                 $hashtied=2;
                   1990: 	    }
                   1991: 	} else {
1.174     albertel 1992: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136     albertel 1993: 		    &GDBM_READER(),0640)) {
1.27      www      1994:                 $hashtied=1;
1.136     albertel 1995: 	    }
                   1996: 	}
1.27      www      1997:     }    
                   1998: }
                   1999: 
                   2000: sub untiehash {
                   2001:     if ($hashtied) { untie %hash; }
                   2002:     $hashtied=0;
1.221     albertel 2003:     return OK;
1.27      www      2004: }
                   2005: 
1.29      www      2006: # --------------------------------------------------------------- check on this
                   2007: 
                   2008: sub checkonthis {
                   2009:     my ($r,$url,$level,$title)=@_;
1.228     www      2010:     $url=&unescape($url);
1.29      www      2011:     $alreadyseen{$url}=1;
                   2012:     $r->rflush();
1.41      www      2013:     if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
1.108     albertel 2014:        $r->print("\n<br />");
1.29      www      2015:        for (my $i=0;$i<=$level*5;$i++) {
                   2016:            $r->print('&nbsp;');
                   2017:        }
                   2018:        $r->print('<a href="'.$url.'" target="cat">'.
                   2019: 		 ($title?$title:$url).'</a> ');
                   2020:        if ($url=~/^\/res\//) {
                   2021: 	  my $result=&Apache::lonnet::repcopy(
                   2022:                               &Apache::lonnet::filelocation('',$url));
1.172     raeburn  2023:           if ($result eq 'ok') {
1.87      www      2024:              $r->print('<font color="green">'.&mt('ok').'</font>');
1.29      www      2025:              $r->rflush();
1.34      www      2026:              &Apache::lonnet::countacc($url);
                   2027:              $url=~/\.(\w+)$/;
                   2028:              if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
                   2029: 		 $r->print('<br />');
                   2030:                  $r->rflush();
                   2031:                  for (my $i=0;$i<=$level*5;$i++) {
                   2032:                      $r->print('&nbsp;');
                   2033:                  }
1.84      www      2034:                  $r->print('- '.&mt('Rendering').': ');
1.170     www      2035: 		 my ($errorcount,$warningcount)=split(/:/,
                   2036: 	       &Apache::lonnet::ssi_body($url,
1.173     albertel 2037: 			       ('grade_target'=>'web',
                   2038: 				'return_only_error_and_warning_counts' => 1)));
1.170     www      2039:                  if (($errorcount) ||
                   2040:                      ($warningcount)) {
                   2041: 		     if ($errorcount) {
1.283     albertel 2042:                         $r->print('<img src="/adm/lonMisc/bomb.gif" /><span class="LC_error">'.
1.170     www      2043: 			  $errorcount.' '.
1.283     albertel 2044: 				  &mt('error(s)').'</span> ');
1.34      www      2045:                      }
1.170     www      2046: 		     if ($warningcount) {
1.283     albertel 2047:                         $r->print('<span class="LC_warning">'.
1.170     www      2048: 			  $warningcount.' '.
1.283     albertel 2049: 				  &mt('warning(s)').'</span>');
1.34      www      2050:                      }
                   2051:                  } else {
1.283     albertel 2052:                      $r->print('<span class="LC_success">'.&mt('ok').'</span>');
1.34      www      2053:                  }
                   2054:                  $r->rflush();
                   2055:              }
1.29      www      2056: 	     my $dependencies=
                   2057:                 &Apache::lonnet::metadata($url,'dependencies');
                   2058:              foreach (split(/\,/,$dependencies)) {
                   2059: 		 if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
                   2060:                     &checkonthis($r,$_,$level+1);
                   2061:                  }
                   2062:              }
1.172     raeburn  2063:           } elsif ($result eq 'unavailable') {
1.283     albertel 2064:              $r->print('<span class="LC_error">'.&mt('connection down').'</span>');
1.172     raeburn  2065:           } elsif ($result eq 'not_found') {
1.100     www      2066: 	      unless ($url=~/\$/) {
1.283     albertel 2067: 		  $r->print('<span class="LC_error">'.&mt('not found').'</b></font>');
1.100     www      2068: 	      } else {
1.283     albertel 2069: 		  $r->print('<span class="LC_unknown">'.&mt('unable to verify variable URL').'</span>');
1.100     www      2070: 	      }
1.29      www      2071:           } else {
1.283     albertel 2072:              $r->print('<span class="LC_error">'.&mt('access denied').'</span>');
1.29      www      2073:           }
                   2074:       }
                   2075:    }
                   2076: }
                   2077: 
1.1       www      2078: 
1.75      www      2079: #
1.208     albertel 2080: # ----------------------------------------------------------------- List Symbs
                   2081: # 
                   2082: sub list_symbs {
1.224     albertel 2083:     my ($r) = @_;
                   2084: 
                   2085:     $r->print(&Apache::loncommon::start_page('Symb List'));
1.257     www      2086:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Symb List'));
1.224     albertel 2087:     my $navmap = Apache::lonnavmaps::navmap->new();
                   2088:     $r->print("<pre>\n");
                   2089:     foreach my $res ($navmap->retrieveResources()) {
                   2090: 	$r->print($res->compTitle()."\t".$res->symb()."\n");
                   2091:     }
                   2092:     $r->print("\n</pre>\n");
                   2093:     $r->print('<a href="/adm/coursedocs">'.&mt('Return to DOCS').'</a>');
1.208     albertel 2094: }
                   2095: 
                   2096: 
                   2097: #
1.75      www      2098: # -------------------------------------------------------------- Verify Content
                   2099: # 
                   2100: sub verifycontent {
1.224     albertel 2101:     my ($r) = @_;
1.230     albertel 2102:     my $type = &Apache::loncommon::course_type();
1.26      www      2103:    my $loaderror=&Apache::lonnet::overloaderror($r);
                   2104:    if ($loaderror) { return $loaderror; }
1.229     raeburn  2105:    $r->print(&Apache::loncommon::start_page('Verify '.$type.' Documents'));
1.257     www      2106:    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$type.' Documents'));
1.27      www      2107:    $hashtied=0;
1.30      www      2108:    undef %alreadyseen;
                   2109:    %alreadyseen=();
1.27      www      2110:    &tiehash();
                   2111:    foreach (keys %hash) {
1.140     www      2112:        if ($hash{$_}=~/\.(page|sequence)$/) {
1.228     www      2113: 	   if (($_=~/^src_/) && ($alreadyseen{&unescape($hash{$_})})) {
1.283     albertel 2114: 	       $r->print('<hr /><span class="LC_error">'.
1.230     albertel 2115: 			 &mt('The following sequence or page is included more than once in your '.$type.': ').
1.283     albertel 2116: 			 &unescape($hash{$_}).'</span><br />'.
1.140     www      2117: 			 &mt('Note that grading records for problems included in this sequence or folder will overlap.<hr />'));
                   2118: 	   }
                   2119:        }
1.228     www      2120:        if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$_})})) {
1.29      www      2121:            &checkonthis($r,$hash{$_},0,$hash{'title_'.$1});
1.27      www      2122:        }
                   2123:    }
                   2124:    &untiehash();
1.108     albertel 2125:    $r->print('<h1>'.&mt('Done').'.</h1>'.'<a href="/adm/coursedocs">'.
                   2126: 	     &mt('Return to DOCS').'</a>');
1.75      www      2127: }
                   2128: 
1.192     www      2129: 
1.75      www      2130: # -------------------------------------------------------------- Check Versions
                   2131: 
1.192     www      2132: sub devalidateversioncache {
                   2133:     my $src=shift;
                   2134:     &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
                   2135: 					  &Apache::lonnet::clutter($src));
                   2136: }
                   2137: 
1.75      www      2138: sub checkversions {
1.224     albertel 2139:     my ($r) = @_;
1.230     albertel 2140:     my $type = &Apache::loncommon::course_type();
1.229     raeburn  2141:     $r->print(&Apache::loncommon::start_page("Check $type Document Versions"));
1.257     www      2142:     $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $type Document Versions"));
1.89      www      2143:     my $header='';
                   2144:     my $startsel='';
                   2145:     my $monthsel='';
                   2146:     my $weeksel='';
                   2147:     my $daysel='';
                   2148:     my $allsel='';
                   2149:     my %changes=();
                   2150:     my $starttime=0;
1.91      www      2151:     my $haschanged=0;
1.92      www      2152:     my %setversions=&Apache::lonnet::dump('resourceversions',
1.174     albertel 2153: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2154: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
1.92      www      2155: 
                   2156:     $hashtied=0;
                   2157:     &tiehash();
                   2158:     my %newsetversions=();
1.174     albertel 2159:     if ($env{'form.setmostrecent'}) {
1.91      www      2160: 	$haschanged=1;
1.92      www      2161: 	foreach (keys %hash) {
                   2162: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
1.93      www      2163: 		$newsetversions{$1}='mostrecent';
1.192     www      2164:                 &devalidateversioncache($1);
1.92      www      2165: 	    }
                   2166: 	}
1.174     albertel 2167:     } elsif ($env{'form.setcurrent'}) {
1.91      www      2168: 	$haschanged=1;
1.92      www      2169: 	foreach (keys %hash) {
                   2170: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
1.93      www      2171: 		my $getvers=&Apache::lonnet::getversion($1);
                   2172: 		if ($getvers>0) {
                   2173: 		    $newsetversions{$1}=$getvers;
1.192     www      2174: 		    &devalidateversioncache($1);
1.93      www      2175: 		}
1.92      www      2176: 	    }
                   2177: 	}
1.174     albertel 2178:     } elsif ($env{'form.setversions'}) {
1.91      www      2179: 	$haschanged=1;
1.174     albertel 2180: 	foreach (keys %env) {
1.92      www      2181: 	    if ($_=~/^form\.set_version_(.+)$/) {
                   2182: 		my $src=$1;
1.174     albertel 2183: 		if (($env{$_}) && ($env{$_} ne $setversions{$src})) {
                   2184: 		    $newsetversions{$src}=$env{$_};
1.192     www      2185: 		    &devalidateversioncache($src);
1.92      www      2186: 		}
                   2187: 	    }
                   2188: 	}
1.91      www      2189:     }
                   2190:     if ($haschanged) {
1.92      www      2191:         if (&Apache::lonnet::put('resourceversions',\%newsetversions,
1.174     albertel 2192: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2193: 			  $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {		
1.272     albertel 2194: 	    $r->print('<h1>'.&mt('Your Version Settings have been Saved').'</h1>');
1.92      www      2195: 	} else {
1.283     albertel 2196: 	    $r->print('<h1><span class="LC_error">'.&mt('An Error Occured while Attempting to Save your Version Settings').'</span></h1>');
1.92      www      2197: 	}
1.136     albertel 2198: 	&mark_hash_old();
1.91      www      2199:     }
1.136     albertel 2200:     &changewarning($r,'');
1.174     albertel 2201:     if ($env{'form.timerange'} eq 'all') {
1.89      www      2202: # show all documents
1.230     albertel 2203: 	$header=&mt('All Documents in '.$type);
1.91      www      2204: 	$allsel=1;
1.90      www      2205: 	foreach (keys %hash) {
                   2206: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
                   2207: 		my $src=$1;
                   2208: 		$changes{$src}=1;
                   2209: 	    }
                   2210: 	}
1.89      www      2211:     } else {
                   2212: # show documents which changed
                   2213: 	%changes=&Apache::lonnet::dump
1.174     albertel 2214: 	 ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
                   2215:                      $env{'course.'.$env{'request.course.id'}.'.num'});
1.89      www      2216: 	my $firstkey=(keys %changes)[0];
                   2217: 	unless ($firstkey=~/^error\:/) {
1.174     albertel 2218: 	    unless ($env{'form.timerange'}) {
                   2219: 		$env{'form.timerange'}=604800;
1.89      www      2220: 	    }
1.174     albertel 2221: 	    my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
1.89      www      2222: 		.&mt('seconds');
1.174     albertel 2223: 	    if ($env{'form.timerange'}==-1) {
1.89      www      2224: 		$seltext='since start of course';
                   2225: 		$startsel='selected';
1.174     albertel 2226: 		$env{'form.timerange'}=time;
1.89      www      2227: 	    }
1.174     albertel 2228: 	    $starttime=time-$env{'form.timerange'};
                   2229: 	    if ($env{'form.timerange'}==2592000) {
1.89      www      2230: 		$seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2231: 		$monthsel='selected';
1.174     albertel 2232: 	    } elsif ($env{'form.timerange'}==604800) {
1.89      www      2233: 		$seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2234: 		$weeksel='selected';
1.174     albertel 2235: 	    } elsif ($env{'form.timerange'}==86400) {
1.89      www      2236: 		$seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2237: 		$daysel='selected';
                   2238: 	    }
                   2239: 	    $header=&mt('Content changed').' '.$seltext;
                   2240: 	} else {
                   2241: 	    $header=&mt('No content modifications yet.');
                   2242: 	}
                   2243:     }
1.92      www      2244:     %setversions=&Apache::lonnet::dump('resourceversions',
1.174     albertel 2245: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2246: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
1.89      www      2247:     my %lt=&Apache::lonlocal::texthash
1.229     raeburn  2248: 	      ('st' => 'Version changes since start of '.$type,
1.88      www      2249: 	       'lm' => 'Version changes since last Month',
                   2250: 	       'lw' => 'Version changes since last Week',
                   2251: 	       'sy' => 'Version changes since Yesterday',
1.91      www      2252:                'al' => 'All Resources (possibly large output)',
1.88      www      2253: 	       'sd' => 'Display',
1.84      www      2254: 	       'fi' => 'File',
                   2255: 	       'md' => 'Modification Date',
1.87      www      2256:                'mr' => 'Most recently published Version',
1.229     raeburn  2257: 	       've' => 'Version used in '.$type,
                   2258:                'vu' => 'Set Version to be used in '.$type,
                   2259: 'sv' => 'Set Versions to be used in '.$type.' according to Selections below',
1.91      www      2260: 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
                   2261: 'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
1.84      www      2262: 	       'di' => 'Differences');
1.89      www      2263:     $r->print(<<ENDHEADERS);
1.31      www      2264: <form action="/adm/coursedocs" method="post">
1.91      www      2265: <input type="hidden" name="versions" value="1" />
                   2266: <input type="submit" name="setmostrecent" value="$lt{'sm'}" />
                   2267: <input type="submit" name="setcurrent" value="$lt{'sc'}" /><hr />
1.31      www      2268: <select name="timerange">
1.88      www      2269: <option value='all' $allsel>$lt{'al'}</option>
1.84      www      2270: <option value="-1" $startsel>$lt{'st'}</option>
                   2271: <option value="2592000" $monthsel>$lt{'lm'}</option>
                   2272: <option value="604800" $weeksel>$lt{'lw'}</option>
                   2273: <option value="86400" $daysel>$lt{'sy'}</option>
1.31      www      2274: </select>
1.91      www      2275: <input type="submit" name="display" value="$lt{'sd'}" />
1.89      www      2276: <h3>$header</h3>
1.91      www      2277: <input type="submit" name="setversions" value="$lt{'sv'}" />
1.103     matthew  2278: <table border="0">
1.31      www      2279: ENDHEADERS
1.91      www      2280:     foreach (sort keys %changes) {
1.89      www      2281: 	if ($changes{$_}>$starttime) {
                   2282: 	    my ($root,$extension)=($_=~/^(.*)\.(\w+)$/);
                   2283: 	    my $currentversion=&Apache::lonnet::getversion($_);
1.93      www      2284: 	    if ($currentversion<0) {
                   2285: 		$currentversion=&mt('Could not be determined.');
                   2286: 	    }
1.89      www      2287: 	    my $linkurl=&Apache::lonnet::clutter($_);
                   2288: 	    $r->print(
1.103     matthew  2289: 		      '<tr><td colspan="5"><br /><br /><font size="+1"><b>'.
1.91      www      2290: 		      &Apache::lonnet::gettitle($linkurl).
1.103     matthew  2291:                       '</b></font></td></tr>'.
                   2292:                       '<tr><td>&nbsp;&nbsp;&nbsp;</td>'.
                   2293:                       '<td colspan="4">'.
                   2294:                       '<a href="'.$linkurl.'" target="cat">'.$linkurl.
                   2295: 		      '</a></td></tr>'.
                   2296:                       '<tr><td></td>'.
                   2297:                       '<td title="'.$lt{'md'}.'">'.
1.102     matthew  2298: 		      &Apache::lonlocal::locallocaltime(
                   2299:                            &Apache::lonnet::metadata($root.'.'.$extension,
                   2300:                                                      'lastrevisiondate')
                   2301:                                                         ).
1.103     matthew  2302:                       '</td>'.
1.284     albertel 2303:                       '<td title="'.$lt{'mr'}.'"><span class="LC_nobreak">Most Recent: '.
1.103     matthew  2304:                       '<font size="+1">'.$currentversion.'</font>'.
1.284     albertel 2305:                       '</span></td>'.
                   2306:                       '<td title="'.$lt{'ve'}.'"><span class="LC_nobreak">In '.$type.': '.
1.103     matthew  2307:                       '<font size="+1">');
1.87      www      2308: # Used in course
1.89      www      2309: 	    my $usedversion=$hash{'version_'.$linkurl};
1.93      www      2310: 	    if (($usedversion) && ($usedversion ne 'mostrecent')) {
1.89      www      2311: 		$r->print($usedversion);
                   2312: 	    } else {
                   2313: 		$r->print($currentversion);
                   2314: 	    }
1.284     albertel 2315: 	    $r->print('</font></span></td><td title="'.$lt{'vu'}.'">'.
                   2316:                       '<span class="LC_nobreak">Use: ');
1.87      www      2317: # Set version
1.92      www      2318: 	    $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
1.89      www      2319: 						      'set_version_'.$linkurl,
1.136     albertel 2320: 						      ('select_form_order' =>
                   2321: 						       ['',1..$currentversion,'mostrecent'],
                   2322: 						       '' => '',
1.93      www      2323: 						       'mostrecent' => 'most recent',
1.89      www      2324: 						       map {$_,$_} (1..$currentversion))));
1.284     albertel 2325: 	    $r->print('</span></td></tr><tr><td></td>');
1.89      www      2326: 	    my $lastold=1;
                   2327: 	    for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
                   2328: 		my $url=$root.'.'.$prevvers.'.'.$extension;
                   2329: 		if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
                   2330: 		    $starttime) {
                   2331: 		    $lastold=$prevvers;
                   2332: 		}
                   2333: 	    }
1.103     matthew  2334:             # 
                   2335:             # Code to figure out how many version entries should go in
                   2336:             # each of the four columns
                   2337:             my $entries_per_col = 0;
                   2338:             my $num_entries = ($currentversion-$lastold);
                   2339:             if ($num_entries % 4 == 0) {
                   2340:                 $entries_per_col = $num_entries/4;
                   2341:             } else {
                   2342:                 $entries_per_col = $num_entries/4 + 1;
                   2343:             }
                   2344:             my $entries_count = 0;
                   2345:             $r->print('<td valign="top"><font size="-2">'); 
                   2346:             my $cols_output = 1;
1.32      www      2347:             for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
1.89      www      2348: 		my $url=$root.'.'.$prevvers.'.'.$extension;
1.284     albertel 2349: 		$r->print('<span class="LC_nobreak"><a href="'.&Apache::lonnet::clutter($url).
1.91      www      2350: 			  '">'.&mt('Version').' '.$prevvers.'</a> ('.
1.103     matthew  2351: 			  &Apache::lonlocal::locallocaltime(
                   2352:                                 &Apache::lonnet::metadata($url,
                   2353:                                                           'lastrevisiondate')
                   2354:                                                             ).
1.91      www      2355: 			  ')');
1.89      www      2356: 		if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
1.33      www      2357:                     $r->print(' <a href="/adm/diff?filename='.
1.89      www      2358: 			      &Apache::lonnet::clutter($root.'.'.$extension).
                   2359: 			      '&versionone='.$prevvers.
                   2360: 			      '">'.&mt('Diffs').'</a>');
                   2361: 		}
1.284     albertel 2362: 		$r->print('</span><br />');
1.103     matthew  2363:                 if (++$entries_count % $entries_per_col == 0) {
                   2364:                     $r->print('</font></td>');
                   2365:                     if ($cols_output != 4) {
                   2366:                         $r->print('<td valign="top"><font size="-2">');
                   2367:                         $cols_output++;
                   2368:                     }
                   2369:                 }
1.89      www      2370: 	    }
1.103     matthew  2371:             while($cols_output++ < 4) {
                   2372:                 $r->print('</font></td><td><font>')
                   2373:             }
                   2374: 	    $r->print('</font></td></tr>'."\n");
1.89      www      2375: 	}
                   2376:     }
1.92      www      2377:     $r->print('</table></form>');
1.89      www      2378:     $r->print('<h1>'.&mt('Done').'.</h1>');
                   2379: 
                   2380:     &untiehash();
1.75      www      2381: }
                   2382: 
1.136     albertel 2383: sub mark_hash_old {
                   2384:     my $retie_hash=0;
                   2385:     if ($hashtied) {
                   2386: 	$retie_hash=1;
                   2387: 	&untiehash();
                   2388:     }
                   2389:     &tiehash('write');
                   2390:     $hash{'old'}=1;
                   2391:     &untiehash();
                   2392:     if ($retie_hash) { &tiehash(); }
                   2393: }
                   2394: 
                   2395: sub is_hash_old {
                   2396:     my $untie_hash=0;
                   2397:     if (!$hashtied) {
                   2398: 	$untie_hash=1;
                   2399: 	&tiehash();
                   2400:     }
                   2401:     my $return=$hash{'old'};
                   2402:     if ($untie_hash) { &untiehash(); }
                   2403:     return $return;
                   2404: }
                   2405: 
1.91      www      2406: sub changewarning {
1.177     albertel 2407:     my ($r,$postexec,$message,$url)=@_;
1.136     albertel 2408:     if (!&is_hash_old()) { return; }
1.150     albertel 2409:     my $pathvar='folderpath';
1.228     www      2410:     my $path=&escape($env{'form.folderpath'});
1.177     albertel 2411:     if (!defined($url)) {
                   2412: 	if (defined($env{'form.pagepath'})) {
                   2413: 	    $pathvar='pagepath';
1.228     www      2414: 	    $path=&escape($env{'form.pagepath'});
                   2415: 	    $path.='&amp;pagesymb='.&escape($env{'form.pagesymb'});
1.177     albertel 2416: 	}
                   2417: 	$url='/adm/coursedocs?'.$pathvar.'='.$path;
                   2418:     }
1.230     albertel 2419:     my $course_type = &Apache::loncommon::course_type();
1.177     albertel 2420:     if (!defined($message)) {
                   2421: 	$message='Changes will become active for your current session after [_1], or the next time you log in.';
1.150     albertel 2422:     }
1.185     www      2423:     $r->print("\n\n".
1.286     albertel 2424: '<script type="text/javascript">function reinit(tf) { tf.submit();'.$postexec.' }</script>'."\n". 
1.185     www      2425: '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'.
1.177     albertel 2426: '<input type="hidden" name="orgurl" value="'.$url.
1.283     albertel 2427: '" /><input type="hidden" name="selectrole" value="1" /><h3><span class="LC_warning">'.
1.177     albertel 2428: &mt($message,' <input type="hidden" name="'.
                   2429:     $env{'request.role'}.'" value="1" /><input type="button" value="'.
1.230     albertel 2430:     &mt('re-initializing '.$course_type).'" onClick="reinit(this.form)" />').
1.283     albertel 2431: $help{'Caching'}.'</span></h3></form>'."\n\n");
1.91      www      2432: }
                   2433: 
1.257     www      2434: # =========================================== Breadcrumbs for special functions
                   2435: 
                   2436: sub init_breadcrumbs {
                   2437:     my ($form,$text)=@_;
                   2438:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2439:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs",
                   2440: 					    text=>&Apache::loncommon::course_type()." Documents",
                   2441: 					    faq=>273,
                   2442: 					    bug=>'Instructor Interface',
                   2443:                                             help => 'Docs_Adding_Course_Doc'});
                   2444:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
                   2445: 					    text=>$text,
                   2446: 					    faq=>273,
                   2447: 					    bug=>'Instructor Interface'});
                   2448: }
                   2449: 
1.75      www      2450: # ================================================================ Main Handler
                   2451: sub handler {
                   2452:     my $r = shift;
1.82      www      2453:     &Apache::loncommon::content_type($r,'text/html');
1.75      www      2454:     $r->send_http_header;
                   2455:     return OK if $r->header_only;
1.230     albertel 2456:     my $type = &Apache::loncommon::course_type();
1.75      www      2457: 
                   2458: # --------------------------------------------- Initialize help topics for this
1.209     albertel 2459:     foreach ('Adding_Course_Doc','Main_Course_Documents',
                   2460: 	     'Adding_External_Resource','Navigate_Content',
                   2461: 	     'Adding_Folders','Docs_Overview', 'Load_Map',
                   2462: 	     'Supplemental','Score_Upload_Form','Adding_Pages',
                   2463: 	     'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
                   2464: 	     'Check_Resource_Versions','Verify_Content') {
                   2465: 	$help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_);
                   2466:     }
1.75      www      2467:     # Composite help files
                   2468:     $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
                   2469: 		    'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
                   2470:     $help{'Simple Page'} = &Apache::loncommon::help_open_topic(
                   2471: 		    'Docs_About_Simple_Page,Docs_Editing_Templated_Pages');
1.86      albertel 2472:     $help{'Simple Problem'} = &Apache::loncommon::help_open_topic(
                   2473: 		    'Option_Response_Simple');
1.75      www      2474:     $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
                   2475: 		    'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
                   2476:     $help{'My Personal Info'} = &Apache::loncommon::help_open_topic(
                   2477: 		  'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
1.255     raeburn  2478:     $help{'Group Files'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
1.75      www      2479:     $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
1.142     raeburn  2480: 
1.209     albertel 2481: # does this user have privileges to modify docs
                   2482:     my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                   2483:   if ($allowed && $env{'form.verify'}) {
1.257     www      2484:       &init_breadcrumbs('verify','Verify Content');
1.75      www      2485:       &verifycontent($r);
1.209     albertel 2486:   } elsif ($allowed && $env{'form.listsymbs'}) {
1.257     www      2487:       &init_breadcrumbs('listsymbs','List Symbs');
1.208     albertel 2488:       &list_symbs($r);
1.247     www      2489:   } elsif ($allowed && $env{'form.docslog'}) {
1.257     www      2490:       &init_breadcrumbs('docslog','Show Log');
1.247     www      2491:       &docs_change_log($r);
1.209     albertel 2492:   } elsif ($allowed && $env{'form.versions'}) {
1.257     www      2493:       &init_breadcrumbs('versions','Check/Set Resource Versions');
1.75      www      2494:       &checkversions($r);
1.209     albertel 2495:   } elsif ($allowed && $env{'form.dumpcourse'}) {
1.257     www      2496:       &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' DOCS to Construction Space');
1.75      www      2497:       &dumpcourse($r);
1.209     albertel 2498:   } elsif ($allowed && $env{'form.exportcourse'}) {
1.257     www      2499:       &init_breadcrumbs('exportcourse','Export '.&Apache::loncommon::course_type().' to IMS');
1.138     raeburn  2500:       &exportcourse($r);
1.26      www      2501:   } else {
1.7       www      2502: # is this a standard course?
                   2503: 
1.174     albertel 2504:     my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
1.155     raeburn  2505:     my $forcestandard = 0;
1.15      www      2506:     my $forcesupplement;
                   2507:     my $script='';
1.19      www      2508:     my $showdoc=0;
1.142     raeburn  2509:     my $containertag;
                   2510:     my $uploadtag;
1.15      www      2511:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.224     albertel 2512: 					    ['folderpath','pagepath',
1.281     albertel 2513: 					     'pagesymb']);
1.174     albertel 2514:     if ($env{'form.folderpath'}) {
                   2515: 	my (@folderpath)=split('&',$env{'form.folderpath'});
1.228     www      2516: 	$env{'form.foldername'}=&unescape(pop(@folderpath));
1.174     albertel 2517: 	$env{'form.folder'}=pop(@folderpath);
                   2518:     }
                   2519:     if ($env{'form.pagepath'}) {
                   2520:         my (@pagepath)=split('&',$env{'form.pagepath'});
1.228     www      2521:         $env{'form.pagename'}=&unescape(pop(@pagepath));
1.174     albertel 2522:         $env{'form.folder'}=pop(@pagepath);
1.156     albertel 2523:         $containertag = '<input type="hidden" name="pagepath" value="" />'.
                   2524: 	    '<input type="hidden" name="pagesymb" value="" />';
1.282     albertel 2525:         $uploadtag = '<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />'.
                   2526: 	    '<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />';
1.142     raeburn  2527:     }
1.21      www      2528:     if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
1.127     albertel 2529:        $showdoc='/'.$1;
1.21      www      2530:     }
                   2531:     unless ($showdoc) { # got called from remote
1.237     albertel 2532:        if (($env{'form.folder'}=~/^(?:group|default)_/) || 
1.209     albertel 2533:           ($env{'form.folder'} =~ m:^\d+/(pages|sequences)/:)) {
1.155     raeburn  2534:            $forcestandard = 1;
                   2535:        } 
1.174     albertel 2536:        $forcesupplement=($env{'form.folder'}=~/^supplemental_/);
1.7       www      2537: 
1.15      www      2538:        if ($allowed) { 
                   2539:          &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
                   2540:          $script=&Apache::lonratedt::editscript('simple'); 
                   2541:        }
                   2542:     } else { # got called in sequence from course
                   2543:        $allowed=0;
1.3       www      2544:     }
1.4       www      2545: 
                   2546: # get course data
1.174     albertel 2547:     my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
                   2548:     my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.4       www      2549: 
1.225     albertel 2550: # get personal data 
1.174     albertel 2551:     my $uname=$env{'user.name'};
                   2552:     my $udom=$env{'user.domain'};
1.245     albertel 2553:     my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom));
1.14      www      2554: 
1.8       www      2555: # graphics settings
1.4       www      2556: 
1.176     albertel 2557:     $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
1.8       www      2558: 
1.224     albertel 2559:     if ($allowed) {
                   2560: 	$script .= &editing_js($udom,$uname);
1.171     www      2561:     }
1.42      www      2562: # -------------------------------------------------------------------- Body tag
1.224     albertel 2563:     $script = '<script type="text/javascript">'."\n".$script."\n".'</script>';
1.229     raeburn  2564:     $r->print(&Apache::loncommon::start_page("$type Documents", $script,
1.225     albertel 2565: 					     {'force_register' => $showdoc,}).
1.233     albertel 2566: 	      &Apache::loncommon::help_open_menu('','',273,'RAT'));
1.224     albertel 2567:   
1.188     raeburn  2568:   my %allfiles = ();
                   2569:   my %codebase = ();
                   2570:   my ($upload_result,$upload_output);
                   2571:   if ($allowed) {
1.264     albertel 2572:       if (($env{'form.uploaddoc.filename'}) &&
                   2573: 	  ($env{'form.cmd'}=~/^upload_(\w+)/)) {
1.188     raeburn  2574: # Process file upload - phase one - upload and parse primary file.  
1.190     albertel 2575:           $upload_result = &process_file_upload(\$upload_output,$coursenum,
                   2576: 						$coursedom,\%allfiles,
1.194     raeburn  2577: 						\%codebase,$1);
1.188     raeburn  2578:           if ($upload_result eq 'phasetwo') {
                   2579:               $r->print($upload_output);
                   2580:           }
                   2581:       } elsif ($env{'form.phasetwo'}) {
                   2582:           my %newname = ();
                   2583:           my %origname = ();
                   2584:           my %attribs = ();
                   2585:           my $updateflag = 0;
                   2586:           my $residx = $env{'form.newidx'};
1.228     www      2587:           my $primary_url = &unescape($env{'form.primaryurl'});
1.188     raeburn  2588: # Process file upload - phase two - gather secondary files.
                   2589:           for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
                   2590:               if ($env{'form.embedded_item_'.$i.'.filename'}) {
                   2591:                   my $javacodebase;
                   2592:                   $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
1.228     www      2593:                   $origname{$i} = &unescape($env{'form.embedded_orig_'.$i});
1.188     raeburn  2594:                   if (exists($env{'form.embedded_codebase_'.$i})) {
1.228     www      2595:                       $javacodebase =  &unescape($env{'form.embedded_codebase_'.$i});  
1.188     raeburn  2596:                       $origname{$i} =~ s#^\Q$javacodebase\E/##; 
                   2597:                   }
                   2598:                   my @attributes = ();
                   2599:                   if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
                   2600:                       @attributes = split/:/,$env{'form.embedded_attrib_'.$i};
                   2601:                   } else {
                   2602:                       @attributes = ($env{'form.embedded_attrib_'.$i});
                   2603:                   }
                   2604:                   foreach (@attributes) {
1.228     www      2605:                       push(@{$attribs{$i}},&unescape($_));
1.188     raeburn  2606:                   }
                   2607:                   if ($javacodebase) {
                   2608:                       $codebase{$i} = $javacodebase;
                   2609:                       $codebase{$i} =~ s#/$##;
                   2610:                       $updateflag = 1;
                   2611:                   }
                   2612:               }
                   2613:               unless ($newname{$i} eq $origname{$i}) {
                   2614:                   $updateflag = 1;
                   2615:               }
                   2616:           }
                   2617: # Process file upload - phase three - modify primary file
                   2618:           if ($updateflag) {
                   2619:               my ($content,$rtncode);
                   2620:               my $updateflag = 0;
                   2621:               my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
                   2622:               if ($getstatus eq 'ok') {
                   2623:                   foreach my $item (keys %newname) {
                   2624:                       if ($newname{$item} ne $origname{$item}) {
                   2625:                           my $attrib_regexp = '';
                   2626:                           if (@{$attribs{$item}} > 1) {
                   2627:                               $attrib_regexp = join('|',@{$attribs{$item}});
                   2628:                           } else {
                   2629:                               $attrib_regexp = $attribs{$item}[0];
                   2630:                           }
                   2631:                           if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
                   2632:                           } 
                   2633:                           $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi; 
                   2634:                       }
                   2635:                       if (exists($codebase{$item})) {
1.224     albertel 2636:                           $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs
1.188     raeburn  2637:                       }
                   2638:                   }
                   2639: # Save edited file.
                   2640:                   my $saveresult;
                   2641:                   my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
                   2642:                   my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.191     raeburn  2643:                   my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
1.188     raeburn  2644:               } else {
                   2645:                   &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus); 
                   2646:               }
                   2647:           }
                   2648:       }
                   2649:   }
                   2650: 
                   2651:   unless ($showdoc ||  $upload_result eq 'phasetwo') {
1.81      www      2652: # -----------------------------------------------------------------------------
                   2653:        my %lt=&Apache::lonlocal::texthash(
1.229     raeburn  2654:                 'uplm' => 'Upload a new main '.lc($type).' document',
                   2655:                 'upls' => 'Upload a new supplemental '.lc($type).' document',
1.168     www      2656:                 'impp' => 'Import a document',
                   2657:                 'pubd' => 'Published documents',
1.181     www      2658: 		'copm' => 'All documents out of a published map into this folder',
1.81      www      2659:                 'spec' => 'Special documents',
                   2660:                 'upld' => 'Upload Document',
                   2661:                 'srch' => 'Search',
                   2662:                 'impo' => 'Import',
1.232     www      2663: 		'book' => 'Import Bookmarks',
1.81      www      2664:                 'selm' => 'Select Map',
                   2665:                 'load' => 'Load Map',
1.186     www      2666:                 'reco' => 'Recover Deleted Resources',
1.81      www      2667:                 'newf' => 'New Folder',
1.142     raeburn  2668:                 'newp' => 'New Composite Page',
1.81      www      2669:                 'extr' => 'External Resource',
                   2670:                 'syll' => 'Syllabus',
                   2671:                 'navc' => 'Navigate Contents',
                   2672:                 'sipa' => 'Simple Page',
                   2673:                 'sipr' => 'Simple Problem',
1.219     www      2674:                 'drbx' => 'Drop Box',
1.81      www      2675:                 'scuf' => 'Score Upload Form',
                   2676:                 'bull' => 'Bulletin Board',
1.96      sakharuk 2677:                 'mypi' => 'My Personal Info',
1.255     raeburn  2678:                 'grpo' => 'Group Files',
1.101     www      2679: 		'abou' => 'About User',
1.110     raeburn  2680:                 'imsf' => 'Import IMS package',
1.96      sakharuk 2681:                 'file' =>  'File',
                   2682:                 'title' => 'Title',
1.188     raeburn  2683:                 'comment' => 'Comment',
                   2684:                 'parse' => 'If HTML file, upload embedded images/multimedia files'
1.81      www      2685: 					  );
                   2686: # -----------------------------------------------------------------------------
1.42      www      2687:     if ($allowed) {
1.281     albertel 2688: 	&update_paste_buffer($coursenum,$coursedom);
1.74      www      2689:        my $dumpbut=&dumpbutton();
1.138     raeburn  2690:        my $exportbut=&exportbutton();
1.88      www      2691:        my %lt=&Apache::lonlocal::texthash(
                   2692: 					 'vc' => 'Verify Content',
                   2693: 					 'cv' => 'Check/Set Resource Versions',
1.208     albertel 2694: 					 'ls' => 'List Symbs',
1.247     www      2695:                                          'sl' => 'Show Log'
1.88      www      2696: 					  );
1.118     albertel 2697: 
1.174     albertel 2698:        my $folderpath=$env{'form.folderpath'};
1.118     albertel 2699:        if (!$folderpath) {
1.174     albertel 2700: 	   if ($env{'form.folder'} eq '' ||
                   2701: 	       $env{'form.folder'} eq 'supplemental') {
1.118     albertel 2702: 	       $folderpath='default&'.
1.230     albertel 2703: 		   &escape(&mt('Main '.$type.' Documents'));
1.118     albertel 2704: 	   }
                   2705:        }
1.174     albertel 2706:        unless ($env{'form.pagepath'}) {
1.142     raeburn  2707:            $containertag = '<input type="hidden" name="folderpath" value="" />';
1.282     albertel 2708:            $uploadtag = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />';
1.142     raeburn  2709:        }
                   2710: 
1.42      www      2711:        $r->print(<<ENDCOURSEVERIFY);
1.36      www      2712: <form name="renameform" method="post" action="/adm/coursedocs">
1.283     albertel 2713:   <input type="hidden" name="title" />
                   2714:   <input type="hidden" name="cmd" />
                   2715:   <input type="hidden" name="markcopy" />
                   2716:   <input type="hidden" name="copyfolder" />
                   2717:   $containertag
1.36      www      2718: </form>
1.39      www      2719: <form name="simpleedit" method="post" action="/adm/coursedocs">
1.283     albertel 2720:   <input type="hidden" name="importdetail" value="" />
                   2721:   $uploadtag
1.39      www      2722: </form>
1.26      www      2723: <form action="/adm/coursedocs" method="post" name="courseverify">
1.283     albertel 2724:   <div class="LC_docs_course_commands">
                   2725: 
                   2726:       <div>
                   2727:         <input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'}
                   2728:       </div>
                   2729:       <div>
                   2730:         <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'}
                   2731:       </div>
                   2732:         $dumpbut
                   2733:         $exportbut
                   2734:       <div>
                   2735:         <input type="submit" name="listsymbs" value="$lt{'ls'}" />
                   2736:       </div>
                   2737:       <div>
                   2738:         <input type="hidden" name="folder" value="$env{'form.folder'}" />
                   2739:         <input type="submit" name="docslog" value="$lt{'sl'}" />
                   2740:       </div>
                   2741:   </div>
1.25      www      2742: </form>
1.283     albertel 2743: <div style="clear: both; height: 0px;">&nbsp;</div>
1.25      www      2744: ENDCOURSEVERIFY
1.74      www      2745:        $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
1.230     albertel 2746: 		     &mt('Editing the Table of Contents for your '.$type)));
1.25      www      2747:     }
1.17      www      2748: # --------------------------------------------------------- Standard documents
1.285     albertel 2749:     $r->print('<table class="LC_docs_documents">');#border=2 cellspacing=4 cellpadding=4>');
1.7       www      2750:     if (($standard) && ($allowed) && (!$forcesupplement)) {
1.285     albertel 2751: 	$r->print('<tr><td class="LC_docs_document">');
1.116     albertel 2752: #  '<h2>'.&mt('Main Course Documents').
                   2753: #  ($allowed?' '.$help{'Main_Course_Documents'}:'').'</h2>');
1.174     albertel 2754:        my $folder=$env{'form.folder'};
1.117     albertel 2755:        if ($folder eq '' || $folder eq 'supplemental') {
1.112     raeburn  2756:            $folder='default';
1.230     albertel 2757: 	   $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$type.' Documents'));
1.112     raeburn  2758:        }
1.51      www      2759:        my $postexec='';
                   2760:        if ($folder eq 'default') {
1.286     albertel 2761: 	   $r->print('<script type="text/javascript">this.window.name="loncapaclient";</script>');
1.51      www      2762:        } else {
1.117     albertel 2763:            #$postexec='self.close();';
1.51      www      2764:        }
1.40      www      2765:        $hadchanges=0;
1.188     raeburn  2766:        &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output);
1.40      www      2767:        if ($hadchanges) {
1.136     albertel 2768: 	   &mark_hash_old()
1.40      www      2769:        }
1.136     albertel 2770:        &changewarning($r,$postexec);
1.16      www      2771:        my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
                   2772:                      '.sequence';
1.142     raeburn  2773:        my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
                   2774:                      '.page';
1.186     www      2775: 	my $container='sequence';
                   2776: 	if ($env{'form.pagepath'}) {
                   2777: 	    $container='page';
                   2778: 	}
                   2779: 	my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
1.8       www      2780:        $r->print(<<ENDFORM);
1.285     albertel 2781: <table class="LC_docs_adddocs">
                   2782: <tr>
                   2783: <th>$lt{'uplm'}</th>
                   2784: <th>$lt{'impp'}</th>
                   2785: <th>$lt{'spec'}</th>
1.11      www      2786: </tr>
1.285     albertel 2787: <tr>
                   2788: <td>
1.96      sakharuk 2789: $lt{'file'}:<br />
1.182     albertel 2790: <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286     albertel 2791: <input type="file" name="uploaddoc" size="40" />
1.8       www      2792: <br />
1.96      sakharuk 2793: $lt{'title'}:<br />
1.286     albertel 2794: <input type="text" size="50" name="comment" />
1.142     raeburn  2795: $uploadtag
1.286     albertel 2796: <input type="hidden" name="cmd" value="upload_default" />
1.188     raeburn  2797: <br />
1.284     albertel 2798: <span class="LC_nobreak">
1.190     albertel 2799: <label>$lt{'parse'}?
1.188     raeburn  2800: <input type="checkbox" name="parserflag" />
1.190     albertel 2801: </label>
1.284     albertel 2802: </span>
1.188     raeburn  2803: <br />
                   2804: <br />
1.284     albertel 2805: <span class="LC_nobreak">
1.286     albertel 2806: <input type="submit" value="$lt{'upld'}" />
1.60      albertel 2807:  $help{'Uploading_From_Harddrive'}
1.284     albertel 2808: </span>
1.60      albertel 2809: </form>
1.11      www      2810: </td>
1.285     albertel 2811: <td>
1.39      www      2812: <form action="/adm/coursedocs" method="post" name="simpleeditdefault">
1.168     www      2813: $lt{'pubd'}<br />
1.142     raeburn  2814: $uploadtag
1.286     albertel 2815: <input type="button" onClick="javascript:groupsearch()" value="$lt{'srch'}" />
1.232     www      2816: <br />
1.284     albertel 2817: <span class="LC_nobreak">
1.286     albertel 2818: <input type="button" onClick="javascript:groupimport();" value="$lt{'impo'}" />
1.58      albertel 2819: $help{'Importing_LON-CAPA_Resource'}
1.284     albertel 2820: </span>
1.232     www      2821: <br />
1.286     albertel 2822: <input type="button" onClick="javascript:groupopen(0,1,1);" value="$lt{'book'}" />
                   2823: <hr />
1.59      www      2824: <p>
1.181     www      2825: $lt{'copm'}<br />
1.282     albertel 2826: <input type="text" size="40" name="importmap" /><br />
1.286     albertel 2827: <span class="LC_nobreak"><input type="button" 
1.52      www      2828: onClick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')"
1.282     albertel 2829: value="$lt{'selm'}" /> <input type="submit" name="loadmap" value="$lt{'load'}" />
1.284     albertel 2830: $help{'Load_Map'}</span>
1.59      www      2831: </p>
1.52      www      2832: </form>
1.186     www      2833: <hr />
                   2834: <form action="/adm/groupsort" method="post" name="recover">
1.232     www      2835: <input type="button" name="recovermap" onClick="javascript:groupopen('$readfile',1,0)" value="$lt{'reco'}" />
1.186     www      2836: </form>
1.142     raeburn  2837: ENDFORM
1.174     albertel 2838:        unless ($env{'form.pagepath'}) {
1.168     www      2839: 	   $r->print(<<ENDFORM);
                   2840: <hr />
                   2841: <form action="/adm/coursedocs" method="post" name="newext">
                   2842: $uploadtag
1.256     albertel 2843: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2844: <span class="LC_nobreak">
1.168     www      2845: <input name="newext" type="button" onClick="javascript:makenewext('newext');"
                   2846: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284     albertel 2847: </span>
1.168     www      2848: </form>
1.214     www      2849: <br /><form action="/adm/imsimportdocs" method="post" name="ims">
1.168     www      2850: <input type="hidden" name="folder" value="$folder" />
                   2851: <input name="imsimport" type="button" value="$lt{'imsf'}" onClick="javascript:makeims();" />
                   2852: </form>
                   2853: ENDFORM
                   2854:        }
1.285     albertel 2855:        $r->print('</td><td>');
1.174     albertel 2856:        unless ($env{'form.pagepath'}) {
1.282     albertel 2857: 	   my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.142     raeburn  2858:            $r->print(<<ENDFORM);
1.214     www      2859: <br /><form action="/adm/coursedocs" method="post" name="newfolder">
1.282     albertel 2860: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 2861: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2862: <span class="LC_nobreak">
1.16      www      2863: <input name="newfolder" type="button"
                   2864: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81      www      2865: value="$lt{'newf'}" />$help{'Adding_Folders'}
1.284     albertel 2866: </span>
1.11      www      2867: </form>
1.214     www      2868: <br /><form action="/adm/coursedocs" method="post" name="newpage">
1.282     albertel 2869: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 2870: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2871: <span class="LC_nobreak">
1.142     raeburn  2872: <input name="newpage" type="button"
                   2873: onClick="javascript:makenewpage(this.form,'$pageseq');"
                   2874: value="$lt{'newp'}" />$help{'Adding_Pages'}
1.284     albertel 2875: </span>
1.142     raeburn  2876: </form>
1.214     www      2877: <br /><form action="/adm/coursedocs" method="post" name="newsyl">
1.142     raeburn  2878: $uploadtag
1.256     albertel 2879: <input type="hidden" name="importdetail" 
                   2880: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.284     albertel 2881: <span class="LC_nobreak">
1.81      www      2882: <input name="newsyl" type="submit" value="$lt{'syll'}" /> 
1.65      bowersj2 2883:  $help{'Syllabus'}
1.284     albertel 2884: </span>
1.58      albertel 2885: </form>
1.214     www      2886: <br /><form action="/adm/coursedocs" method="post" name="newnav">
1.142     raeburn  2887: $uploadtag
1.256     albertel 2888: <input type="hidden" name="importdetail" 
                   2889: value="Navigate Content=/adm/navmaps" />
1.284     albertel 2890: <span class="LC_nobreak">
1.81      www      2891: <input name="newnav" type="submit" value="$lt{'navc'}" />
1.47      www      2892: $help{'Navigate_Content'}
1.284     albertel 2893: </span>
1.22      www      2894: </form>
1.214     www      2895: <br /><form action="/adm/coursedocs" method="post" name="newsmppg">
1.142     raeburn  2896: $uploadtag
1.256     albertel 2897: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2898: <span class="LC_nobreak">
1.81      www      2899: <input name="newsmppg" type="button" value="$lt{'sipa'}"
1.65      bowersj2 2900: onClick="javascript:makesmppage();" /> $help{'Simple Page'}
1.284     albertel 2901: </span>
1.55      www      2902: </form>
1.214     www      2903: <br /><form action="/adm/coursedocs" method="post" name="newsmpproblem">
1.142     raeburn  2904: $uploadtag
1.256     albertel 2905: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2906: <span class="LC_nobreak">
1.81      www      2907: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
1.65      bowersj2 2908: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284     albertel 2909: </span>
1.62      www      2910: </form>
1.219     www      2911: <br /><form action="/adm/coursedocs" method="post" name="newdropbox">
                   2912: $uploadtag      
1.256     albertel 2913: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2914: <span class="LC_nobreak">          
1.219     www      2915: <input name="newdropbox" type="button" value="$lt{'drbx'}"
                   2916: onClick="javascript:makedropbox();" />
1.284     albertel 2917: </span>         
1.219     www      2918: </form> 
1.214     www      2919: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142     raeburn  2920: $uploadtag
1.256     albertel 2921: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2922: <span class="LC_nobreak">
1.81      www      2923: <input name="newexamupload" type="button" value="$lt{'scuf'}"
1.62      www      2924: onClick="javascript:makeexamupload();" />
1.66      bowersj2 2925: $help{'Score_Upload_Form'}
1.284     albertel 2926: </span>
1.22      www      2927: </form>
1.214     www      2928: <br /><form action="/adm/coursedocs" method="post" name="newbul">
1.142     raeburn  2929: $uploadtag
1.256     albertel 2930: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2931: <span class="LC_nobreak">
1.81      www      2932: <input name="newbulletin" type="button" value="$lt{'bull'}"
1.22      www      2933: onClick="javascript:makebulboard();" />
1.65      bowersj2 2934: $help{'Bulletin Board'}
1.284     albertel 2935: </span>
1.58      albertel 2936: </form>
1.214     www      2937: <br /><form action="/adm/coursedocs" method="post" name="newaboutme">
1.142     raeburn  2938: $uploadtag
1.256     albertel 2939: <input type="hidden" name="importdetail" 
                   2940: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284     albertel 2941: <span class="LC_nobreak">
1.81      www      2942: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65      bowersj2 2943: $help{'My Personal Info'}
1.284     albertel 2944: </span>
1.101     www      2945: </form>
1.214     www      2946: <br /><form action="/adm/coursedocs" method="post" name="newaboutsomeone">
1.142     raeburn  2947: $uploadtag
1.256     albertel 2948: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2949: <span class="LC_nobreak">
1.101     www      2950: <input name="newaboutsomeone" type="button" value="$lt{'abou'}" 
                   2951: onClick="javascript:makeabout();" />
1.284     albertel 2952: </span>
1.182     albertel 2953: </form>
1.255     raeburn  2954: <br /><form action="/adm/coursedocs" method="post" name="newgroupfiles">
                   2955: $uploadtag
1.256     albertel 2956: <input type="hidden" name="importdetail"
                   2957: value="Group Files=/adm/$coursedom/$coursenum/aboutme" />
1.284     albertel 2958: <span class="LC_nobreak">
1.255     raeburn  2959: <input name="newgroupfiles" type="submit" value="$lt{'grpo'}" />
                   2960: $help{'Group Files'}
1.284     albertel 2961: </span>
1.255     raeburn  2962: </form>
1.142     raeburn  2963: ENDFORM
                   2964:        }
1.174     albertel 2965:        if ($env{'form.pagepath'}) {
1.142     raeburn  2966:            $r->print(<<ENDBLOCK);
                   2967: <form action="/adm/coursedocs" method="post" name="newsmpproblem">
                   2968: $uploadtag
1.256     albertel 2969: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2970: <span class="LC_nobreak">
1.142     raeburn  2971: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
                   2972: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284     albertel 2973: </span>
1.142     raeburn  2974: </form>
1.214     www      2975: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142     raeburn  2976: $uploadtag
1.256     albertel 2977: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2978: <span class="LC_nobreak">
1.142     raeburn  2979: <input name="newexamupload" type="button" value="$lt{'scuf'}"
                   2980: onClick="javascript:makeexamupload();" />
                   2981: $help{'Score_Upload_Form'}
1.284     albertel 2982: </span>
1.182     albertel 2983: </form>
1.142     raeburn  2984: ENDBLOCK
                   2985:        }
                   2986:        $r->print('</td></tr>'."\n".
                   2987: '</table>');
1.24      www      2988:        $r->print('</td></tr>');
1.7       www      2989:     }
                   2990: # ----------------------------------------------------- Supplemental documents
                   2991:     if (!$forcestandard) {
1.285     albertel 2992:        $r->print('<tr><td class="LC_docs_document">');
1.116     albertel 2993: # '<h2>'.&mt('Supplemental Course Documents').
                   2994: #  ($allowed?' '.$help{'Supplemental'}:'').'</h2>');
1.174     albertel 2995:        my $folder=$env{'form.folder'};
1.117     albertel 2996:        unless ($folder=~/^supplemental/) {
1.116     albertel 2997: 	   $folder='supplemental';
1.117     albertel 2998:        }
                   2999:        if ($folder =~ /^supplemental$/ &&
1.174     albertel 3000: 	   $env{'form.folderpath'} =~ /^default\&/) {
                   3001: 	   $env{'form.folderpath'}='supplemental&'.
1.230     albertel 3002: 	       &escape(&mt('Supplemental '.$type.' Documents'));
1.116     albertel 3003:        }
1.7       www      3004:        &editor($r,$coursenum,$coursedom,$folder,$allowed);
1.8       www      3005:        if ($allowed) {
1.282     albertel 3006: 	   my $folderseq=
                   3007: 	       '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
                   3008: 	       '.sequence';
1.17      www      3009: 
1.282     albertel 3010: 	   my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   3011: 	   $r->print(<<ENDSUPFORM);
1.285     albertel 3012: <table class="LC_docs_adddocs"><tr>
                   3013: <th>$lt{'upls'}</th>
                   3014: <th>$lt{'spec'}</th>
1.17      www      3015: </tr>
1.285     albertel 3016: <tr><td>
1.10      www      3017: <form action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286     albertel 3018: <input type="file" name="uploaddoc" size="40" />
1.196     raeburn  3019: <br />
                   3020: <br />
1.284     albertel 3021: <span class="LC_nobreak">
1.196     raeburn  3022: <label>$lt{'parse'}?
                   3023: <input type="checkbox" name="parserflag" />
                   3024: </label>
1.284     albertel 3025: </span>
1.196     raeburn  3026: <br /><br />
                   3027: $lt{'comment'}:<br />
1.4       www      3028: <textarea cols=50 rows=4 name='comment'>
                   3029: </textarea>
1.115     albertel 3030: <br />
1.282     albertel 3031: <input type="hidden" name="folderpath" value="$path" />
1.286     albertel 3032: <input type="hidden" name="cmd" value="upload_supplemental" />
1.284     albertel 3033: <span class="LC_nobreak">
1.286     albertel 3034: <input type="submit" value="$lt{'upld'}" />
1.58      albertel 3035:  $help{'Uploading_From_Harddrive'}
1.284     albertel 3036: </span>
1.58      albertel 3037: </form>
1.17      www      3038: </td>
1.285     albertel 3039: <td>
1.18      www      3040: <form action="/adm/coursedocs" method="post" name="supnewfolder">
1.282     albertel 3041: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3042: <input type="hidden" name="importdetail" value="" />
1.284     albertel 3043: <span class="LC_nobreak">
1.17      www      3044: <input name="newfolder" type="button"
                   3045: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81      www      3046: value="$lt{'newf'}" /> $help{'Adding_Folders'}
1.284     albertel 3047: </span>
1.17      www      3048: </form>
1.214     www      3049: <br /><form action="/adm/coursedocs" method="post" name="supnewext">
1.282     albertel 3050: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3051: <input type="hidden" name="importdetail" value="" />
1.284     albertel 3052: <span class="LC_nobreak">
1.18      www      3053: <input name="newext" type="button" 
                   3054: onClick="javascript:makenewext('supnewext');"
1.81      www      3055: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284     albertel 3056: </span>
1.17      www      3057: </form>
1.214     www      3058: <br /><form action="/adm/coursedocs" method="post" name="supnewsyl">
1.282     albertel 3059: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3060: <input type="hidden" name="importdetail" 
                   3061: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.284     albertel 3062: <span class="LC_nobreak">
1.81      www      3063: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65      bowersj2 3064: $help{'Syllabus'}
1.284     albertel 3065: </span>
1.58      albertel 3066: </form>
1.214     www      3067: <br /><form action="/adm/coursedocs" method="post" name="subnewaboutme">
1.282     albertel 3068: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3069: <input type="hidden" name="importdetail" 
                   3070: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284     albertel 3071: <span class="LC_nobreak">
1.81      www      3072: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65      bowersj2 3073: $help{'My Personal Info'}
1.284     albertel 3074: </span>
1.58      albertel 3075: </form>
1.17      www      3076: </td></tr>
1.24      www      3077: </table></td></tr>
1.8       www      3078: ENDSUPFORM
                   3079:        }
1.7       www      3080:     }
1.286     albertel 3081:     $r->print('</table>');
1.18      www      3082:     if ($allowed) {
1.287     albertel 3083: 	$r->print('
                   3084: <form method="post" name="extimport" action="/adm/coursedocs">
                   3085:   <input type="hidden" name="title" />
                   3086:   <input type="hidden" name="url" />
                   3087:   <input type="hidden" name="useform" />
                   3088:   <input type="hidden" name="residx" />
                   3089: </form>');
1.18      www      3090:     }
1.19      www      3091:   } else {
1.188     raeburn  3092:       unless ($upload_result eq 'phasetwo') {
1.19      www      3093: # -------------------------------------------------------- This is showdoc mode
1.188     raeburn  3094:           $r->print("<h1>".&mt('Uploaded Document').' - '.
1.141     albertel 3095: 		&Apache::lonnet::gettitle($r->uri).'</h1><p>'.
1.286     albertel 3096: &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><table>".
                   3097:           &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table>');
1.188     raeburn  3098:       }
1.19      www      3099:   }
1.26      www      3100:  }
1.224     albertel 3101:  $r->print(&Apache::loncommon::end_page());
1.26      www      3102:  return OK;
1.1       www      3103: } 
                   3104: 
1.224     albertel 3105: 
                   3106: sub editing_js {
                   3107:     my ($udom,$uname) = @_;
                   3108:     my $now = time();
                   3109: 
                   3110:     return <<ENDNEWSCRIPT;
                   3111: function makenewfolder(targetform,folderseq) {
                   3112:     var foldername=prompt('Name of New Folder','New Folder');
                   3113:     if (foldername) {
1.236     albertel 3114:        targetform.importdetail.value=escape(foldername)+"="+folderseq;
1.224     albertel 3115:         targetform.submit();
                   3116:     }
                   3117: }
                   3118: 
                   3119: function makenewpage(targetform,folderseq) {
                   3120:     var pagename=prompt('Name of New Page','New Page');
                   3121:     if (pagename) {
1.236     albertel 3122:         targetform.importdetail.value=escape(pagename)+"="+folderseq;
1.224     albertel 3123:         targetform.submit();
                   3124:     }
                   3125: }
                   3126: 
                   3127: function makenewext(targetname) {
                   3128:     this.document.forms.extimport.useform.value=targetname;
1.287     albertel 3129:     this.document.forms.extimport.title.value='';
                   3130:     this.document.forms.extimport.url.value='';
                   3131:     this.document.forms.extimport.residx.value='';
                   3132:     window.open('/adm/rat/extpickframe.html');
                   3133: }
                   3134: 
                   3135: function edittext(targetname,residx,title,url) {
                   3136:     this.document.forms.extimport.useform.value=targetname;
                   3137:     this.document.forms.extimport.residx.value=residx;
                   3138:     this.document.forms.extimport.url.value=url;
                   3139:     this.document.forms.extimport.title.value=title;
1.224     albertel 3140:     window.open('/adm/rat/extpickframe.html');
                   3141: }
                   3142: 
                   3143: function makeexamupload() {
                   3144:    var title=prompt('Listed Title for the Uploaded Score');
                   3145:    if (title) { 
                   3146:     this.document.forms.newexamupload.importdetail.value=
1.236     albertel 3147: 	escape(title)+'=/res/lib/templates/examupload.problem';
1.224     albertel 3148:     this.document.forms.newexamupload.submit();
                   3149:    }
                   3150: }
                   3151: 
                   3152: function makesmppage() {
                   3153:    var title=prompt('Listed Title for the Page');
                   3154:    if (title) { 
                   3155:     this.document.forms.newsmppg.importdetail.value=
1.236     albertel 3156: 	escape(title)+'=/adm/$udom/$uname/$now/smppg';
1.224     albertel 3157:     this.document.forms.newsmppg.submit();
                   3158:    }
                   3159: }
                   3160: 
                   3161: function makesmpproblem() {
                   3162:    var title=prompt('Listed Title for the Problem');
                   3163:    if (title) { 
                   3164:     this.document.forms.newsmpproblem.importdetail.value=
1.236     albertel 3165: 	escape(title)+'=/res/lib/templates/simpleproblem.problem';
1.224     albertel 3166:     this.document.forms.newsmpproblem.submit();
                   3167:    }
                   3168: }
                   3169: 
                   3170: function makedropbox() {
                   3171:    var title=prompt('Listed Title for the Drop Box');
                   3172:    if (title) { 
                   3173:     this.document.forms.newdropbox.importdetail.value=
1.236     albertel 3174:         escape(title)+'=/res/lib/templates/DropBox.problem';
1.224     albertel 3175:     this.document.forms.newdropbox.submit();
                   3176:    }
                   3177: }
                   3178: 
                   3179: function makebulboard() {
                   3180:    var title=prompt('Listed Title for the Bulletin Board');
                   3181:    if (title) {
                   3182:     this.document.forms.newbul.importdetail.value=
1.236     albertel 3183: 	escape(title)+'=/adm/$udom/$uname/$now/bulletinboard';
1.224     albertel 3184:     this.document.forms.newbul.submit();
                   3185:    }
                   3186: }
                   3187: 
                   3188: function makeabout() {
1.236     albertel 3189:    var user=prompt("Enter user:domain for User's 'About Me' Page");
1.224     albertel 3190:    if (user) {
                   3191:        var comp=new Array();
1.236     albertel 3192:        comp=user.split(':');
1.224     albertel 3193:        if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) {
                   3194: 	   if ((comp[0]) && (comp[1])) {
                   3195: 	       this.document.forms.newaboutsomeone.importdetail.value=
1.236     albertel 3196: 		   'About '+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme';
1.224     albertel 3197: 	       this.document.forms.newaboutsomeone.submit();
                   3198: 	   } else {
1.236     albertel 3199:                alert("Not a valid user:domain");
1.224     albertel 3200:            }
                   3201:        } else {
1.236     albertel 3202:            alert("Please enter both user and domain in the format user:domain"); 
1.224     albertel 3203:        }
                   3204:    }
                   3205: }
                   3206: 
                   3207: function makeims() {
                   3208:     var caller = document.forms.ims.folder.value;
                   3209:     var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one";
                   3210:     newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes");
                   3211:     newWindow.location.href = newlocation;
                   3212: }
                   3213: 
                   3214: 
                   3215: function finishpick() {
                   3216:     var title=this.document.forms.extimport.title.value;
                   3217:     var url=this.document.forms.extimport.url.value;
                   3218:     var form=this.document.forms.extimport.useform.value;
1.287     albertel 3219:     var residx=this.document.forms.extimport.residx.value;
                   3220:     eval('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+'='+residx+'";this.document.forms.'+form+'.submit();');
1.224     albertel 3221: }
                   3222: 
                   3223: function changename(folderpath,index,oldtitle,container,pagesymb) {
                   3224:     var title=prompt('New Title',oldtitle);
                   3225:     if (title) {
1.281     albertel 3226: 	this.document.forms.renameform.markcopy.value=-1;
1.224     albertel 3227: 	this.document.forms.renameform.title.value=title;
                   3228: 	this.document.forms.renameform.cmd.value='rename_'+index;
                   3229:         if (container == 'sequence') {
                   3230: 	    this.document.forms.renameform.folderpath.value=folderpath;
                   3231:         }
                   3232:         if (container == 'page') {
                   3233:             this.document.forms.renameform.pagepath.value=folderpath;
                   3234:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3235:         }
                   3236:         this.document.forms.renameform.submit();
                   3237:     }
                   3238: }
                   3239: 
                   3240: function removeres(folderpath,index,oldtitle,container,pagesymb) {
                   3241:     if (confirm('WARNING: Removing a resource makes associated grades and scores inaccessible!\\nRemove "'+oldtitle+'"?')) {
1.281     albertel 3242: 	this.document.forms.renameform.markcopy.value=-1;
1.224     albertel 3243: 	this.document.forms.renameform.cmd.value='del_'+index;
                   3244:         if (container == 'sequence') {
                   3245:             this.document.forms.renameform.folderpath.value=folderpath;
                   3246:         }
                   3247:         if (container == 'page') {
                   3248:             this.document.forms.renameform.pagepath.value=folderpath;
                   3249:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3250:         }
                   3251:         this.document.forms.renameform.submit();
                   3252:     }
                   3253: }
                   3254: 
1.281     albertel 3255: function cutres(folderpath,index,oldtitle,container,pagesymb,folder) {
1.224     albertel 3256:     if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible!\\nGrades remain inaccessible if resource is pasted into another folder.\\nCut "'+oldtitle+'"?')) {
                   3257: 	this.document.forms.renameform.cmd.value='cut_'+index;
                   3258: 	this.document.forms.renameform.markcopy.value=index;
1.281     albertel 3259: 	this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224     albertel 3260:         if (container == 'sequence') {
                   3261:             this.document.forms.renameform.folderpath.value=folderpath;
                   3262:         }
                   3263:         if (container == 'page') {
                   3264:             this.document.forms.renameform.pagepath.value=folderpath;
                   3265:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3266:         }
                   3267:         this.document.forms.renameform.submit();
                   3268:     }
                   3269: }
                   3270: 
1.281     albertel 3271: function markcopy(folderpath,index,oldtitle,container,pagesymb,folder) {
1.224     albertel 3272:     this.document.forms.renameform.markcopy.value=index;
1.281     albertel 3273:     this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224     albertel 3274:     if (container == 'sequence') {
                   3275: 	this.document.forms.renameform.folderpath.value=folderpath;
                   3276:     }
                   3277:     if (container == 'page') {
                   3278: 	this.document.forms.renameform.pagepath.value=folderpath;
                   3279: 	this.document.forms.renameform.pagesymb.value=pagesymb;
                   3280:     }
                   3281:     this.document.forms.renameform.submit();
                   3282: }
                   3283: 
                   3284: ENDNEWSCRIPT
                   3285: }
1.1       www      3286: 1;
                   3287: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>