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

1.1       www         1: # The LearningOnline Network
1.2       www         2: # Documents
1.1       www         3: #
1.287   ! albertel    4: # $Id: londocs.pm,v 1.286 2007/07/04 00:21:42 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.287   ! albertel  935: 	    if (!$residx) {
        !           936: 		$residx = &LONCAPA::map::getresidx($url);
        !           937: 		$LONCAPA::map::order[$#LONCAPA::map::order+1]=$residx;
        !           938: 	    }
1.73      bowersj2  939: 	    my $ext = 'false';
1.263     albertel  940: 	    if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
1.273     albertel  941: 	    $url  = &LONCAPA::map::qtunescape($url);
                    942: 	    $name = &LONCAPA::map::qtunescape($name);
1.287   ! albertel  943: 	    $LONCAPA::map::resources[$residx] = 
        !           944: 		join(':', ($name, $url, $ext, 'normal', 'res'));
1.73      bowersj2  945: 	}
                    946:     }
1.142     raeburn   947:     return &storemap($coursenum, $coursedom, $folder.'.'.$container);
1.73      bowersj2  948: }
                    949: 
1.114     albertel  950: sub breadcrumbs {
                    951:     my ($where)=@_;
                    952:     &Apache::lonhtmlcommon::clear_breadcrumbs();
1.142     raeburn   953:     my (@folders);
1.174     albertel  954:     if ($env{'form.pagepath'}) {
                    955:         @folders = split('&',$env{'form.pagepath'});
1.142     raeburn   956:     } else {
1.174     albertel  957:         @folders=split('&',$env{'form.folderpath'});
1.142     raeburn   958:     }
1.116     albertel  959:     my $folderpath;
1.168     www       960:     my $cpinfo='';
1.251     www       961:     my $plain='';
1.242     www       962:     my $randompick=-1;
                    963:     my $isencrypted=0;
                    964:     my $ishidden=0;
1.116     albertel  965:     while (@folders) {
                    966: 	my $folder=shift(@folders);
                    967: 	my $foldername=shift(@folders);
                    968: 	if ($folderpath) {$folderpath.='&';}
                    969: 	$folderpath.=$folder.'&'.$foldername;
                    970: 	my $url='/adm/coursedocs?folderpath='.
1.228     www       971: 	    &escape($folderpath);
1.242     www       972:             my $name=&unescape($foldername);
                    973: # randompick number, hidden, encrypted is appended with ":"s to the foldername	
                    974:             $name=~s/\:(\d*)\:(\w*)\:(\w*)$//;
                    975:             if ($1 ne '') { 
                    976:                $randompick=$1;
                    977:             } else {
                    978:                $randompick=-1;
                    979:             }
                    980:             if ($2) { $ishidden=1; }
                    981:             if ($3) { $isencrypted=1; }
1.114     albertel  982: 	    &Apache::lonhtmlcommon::add_breadcrumb(
1.168     www       983: 		      {'href'=>$url.$cpinfo,
1.242     www       984: 		       'title'=>$name,
1.117     albertel  985: 		       'text'=>'<font size="+1">'.
1.266     albertel  986: 			   $name.'</font>',
                    987: 		       'no_mt'=>1,
1.117     albertel  988: 		       });
1.251     www       989: 	$plain.=$name.' &gt; ';
1.114     albertel  990:     }
1.251     www       991:     $plain=~s/\&gt\;\s*$//;
1.242     www       992:     return (&Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'nohelp',
1.251     www       993: 					       'LC_docs_path'),$randompick,$ishidden,$isencrypted,$plain);
1.114     albertel  994: }
                    995: 
1.247     www       996: sub log_docs {
                    997:     return &Apache::lonnet::instructor_log('docslog',@_);
                    998: }
                    999: 
                   1000: {
                   1001:     my @oldresources=();
                   1002:     my @oldorder=();
                   1003:     my $parmidx;
                   1004:     my %parmaction=();
                   1005:     my %parmvalue=();
1.249     www      1006:     my $changedflag;
1.247     www      1007: 
                   1008:     sub snapshotbefore {
1.248     albertel 1009:         @oldresources=@LONCAPA::map::resources;
                   1010:         @oldorder=@LONCAPA::map::order;
1.247     www      1011:         $parmidx=undef;
                   1012:         %parmaction=();
                   1013:         %parmvalue=();
1.249     www      1014:         $changedflag=0;
1.247     www      1015:     }
                   1016: 
                   1017:     sub remember_parms {
                   1018:         my ($idx,$parameter,$action,$value)=@_;
                   1019:         $parmidx=$idx;
                   1020:         $parmaction{$parameter}=$action;
                   1021:         $parmvalue{$parameter}=$value;
1.249     www      1022:         $changedflag=1;
1.247     www      1023:     }
                   1024: 
                   1025:     sub log_differences {
1.251     www      1026:         my ($plain)=@_;
1.260     www      1027:         my %storehash=('folder' => $plain,
                   1028:                        'currentfolder' => $env{'form.folder'});
1.247     www      1029:         if ($parmidx) {
                   1030:            $storehash{'parameter_res'}=$oldresources[$parmidx];
                   1031:            foreach my $parm (keys %parmaction) {
                   1032:               $storehash{'parameter_action_'.$parm}=$parmaction{$parm};
                   1033:               $storehash{'parameter_value_'.$parm}=$parmvalue{$parm};
                   1034:            }
                   1035:         }
                   1036:         my $maxidx=$#oldresources;
1.248     albertel 1037:         if ($#LONCAPA::map::resources>$#oldresources) {
                   1038:            $maxidx=$#LONCAPA::map::resources;
1.247     www      1039:         }
                   1040:         for (my $idx=0; $idx<=$maxidx; $idx++) {
                   1041:            if ($LONCAPA::map::resources[$idx] ne $oldresources[$idx]) {
                   1042:               $storehash{'before_resources_'.$idx}=$oldresources[$idx];
                   1043:               $storehash{'after_resources_'.$idx}=$LONCAPA::map::resources[$idx];
1.249     www      1044:               $changedflag=1;
1.247     www      1045:            }
                   1046:            if ($LONCAPA::map::order[$idx] ne $oldorder[$idx]) {
1.252     www      1047:               $storehash{'before_order_res_'.$idx}=$oldresources[$oldorder[$idx]];
                   1048:               $storehash{'after_order_res_'.$idx}=$LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
1.249     www      1049:               $changedflag=1;
1.247     www      1050:            }
                   1051:         }
1.251     www      1052: 	$storehash{'maxidx'}=$maxidx;
1.249     www      1053:         if ($changedflag) { &log_docs(\%storehash); }
1.247     www      1054:     }
                   1055: }
                   1056: 
                   1057: 
                   1058: #
                   1059: # Docs Change Log
                   1060: #
                   1061: sub docs_change_log {
                   1062:     my ($r)=@_;
1.260     www      1063:     my $folder=$env{'form.folder'};
1.247     www      1064:     $r->print(&Apache::loncommon::start_page('Course Document Change Log'));
                   1065:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Document Change Log'));
                   1066:     my %docslog=&Apache::lonnet::dump('nohist_docslog',
                   1067:                                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                   1068:                                       $env{'course.'.$env{'request.course.id'}.'.num'});
1.254     albertel 1069: 
1.247     www      1070:     if ((keys(%docslog))[0]=~/^error\:/) { undef(%docslog); }
1.254     albertel 1071: 
1.247     www      1072:     $r->print('<form action="/adm/coursedocs" method="post" name="docslog">'.
                   1073:               '<input type="hidden" name="docslog" value="1" />');
1.254     albertel 1074: 
1.247     www      1075:     my %saveable_parameters = ('show' => 'scalar',);
                   1076:     &Apache::loncommon::store_course_settings('docs_log',
                   1077:                                               \%saveable_parameters);
                   1078:     &Apache::loncommon::restore_course_settings('docs_log',
                   1079:                                                 \%saveable_parameters);
                   1080:     if (!$env{'form.show'}) { $env{'form.show'}=10; }
1.254     albertel 1081:     my %lt=('hiddenresource' => 'Resources hidden',
                   1082: 	    'encrypturl'     => 'URL hidden',
                   1083: 	    'randompick'     => 'Randomly pick',
                   1084: 	    'set'            => 'set to',
                   1085: 	    'del'            => 'deleted');
1.259     www      1086:     $r->print(&Apache::loncommon::display_filter().
1.260     www      1087:               '<input type="hidden" name="folder" value="'.$folder.'" />'.
1.247     www      1088:               '<input type="submit" value="'.&mt('Display').'" /></form>');
                   1089:     $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row().
1.251     www      1090:               '<th>'.&mt('Time').'</th><th>'.&mt('User').'</th><th>'.&mt('Folder').'</th><th>'.&mt('Before').'</th><th>'.
                   1091:               &mt('After').'</th>'.
1.247     www      1092:               &Apache::loncommon::end_data_table_header_row());
                   1093:     my $shown=0;
                   1094:     foreach my $id (sort { $docslog{$b}{'exe_time'}<=>$docslog{$a}{'exe_time'} } (keys(%docslog))) {
1.260     www      1095: 	if ($env{'form.displayfilter'} eq 'currentfolder') {
                   1096: 	    if ($docslog{$id}{'logentry'}{'currentfolder'} ne $folder) { next; }
                   1097: 	}
1.247     www      1098:         my @changes=keys(%{$docslog{$id}{'logentry'}});
1.261     www      1099:         if ($env{'form.displayfilter'} eq 'containing') {
                   1100: 	    my $wholeentry=$docslog{$id}{'exe_uname'}.':'.$docslog{$id}{'exe_udom'}.':'.
                   1101: 		&Apache::loncommon::plainname($docslog{$id}{'exe_uname'},$docslog{$id}{'exe_udom'});
                   1102: 	    foreach my $key (@changes) {
                   1103: 		$wholeentry.=':'.$docslog{$id}{'logentry'}{$key};
                   1104: 	    }
                   1105: 	    if ($wholeentry!~/\Q$env{'form.containingphrase'}\E/i) { next; }         
                   1106: 	}
1.247     www      1107:         my $count = 0;
                   1108:         my $time =
                   1109:             &Apache::lonlocal::locallocaltime($docslog{$id}{'exe_time'});
                   1110:         my $plainname =
                   1111:             &Apache::loncommon::plainname($docslog{$id}{'exe_uname'},
                   1112:                                           $docslog{$id}{'exe_udom'});
                   1113:         my $about_me_link =
                   1114:             &Apache::loncommon::aboutmewrapper($plainname,
                   1115:                                                $docslog{$id}{'exe_uname'},
                   1116:                                                $docslog{$id}{'exe_udom'});
                   1117:         my $send_msg_link='';
                   1118:         if ((($docslog{$id}{'exe_uname'} ne $env{'user.name'})
                   1119:              || ($docslog{$id}{'exe_udom'} ne $env{'user.domain'}))) {
                   1120:             $send_msg_link ='<br />'.
                   1121:                 &Apache::loncommon::messagewrapper(&mt('Send message'),
                   1122:                                                    $docslog{$id}{'exe_uname'},
                   1123:                                                    $docslog{$id}{'exe_udom'});
                   1124:         }
                   1125:         $r->print(&Apache::loncommon::start_data_table_row());
                   1126:         $r->print('<td>'.$time.'</td>
                   1127:                        <td>'.$about_me_link.
                   1128:                   '<br /><tt>'.$docslog{$id}{'exe_uname'}.
                   1129:                                   ':'.$docslog{$id}{'exe_udom'}.'</tt>'.
1.249     www      1130:                   $send_msg_link.'</td><td>'.
1.251     www      1131:                   $docslog{$id}{'logentry'}{'folder'}.'</td><td>');
                   1132: # Before
                   1133: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1134: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                   1135: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
                   1136: 	    if ($oldname ne $newname) {
1.252     www      1137: 		$r->print(&LONCAPA::map::qtescape($oldname));
1.251     www      1138: 	    }
                   1139: 	}
1.252     www      1140: 	$r->print('<ul>');
                   1141: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1142:             if ($docslog{$id}{'logentry'}{'before_order_res_'.$idx}) {
                   1143: 		$r->print('<li>'.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'before_order_res_'.$idx}))[0]).'</li>');
                   1144: 	    }
                   1145: 	}
                   1146: 	$r->print('</ul>');
1.251     www      1147: # After
                   1148:         $r->print('</td><td>');
                   1149: 
                   1150: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1151: 	    my $oldname=(split(/\:/,$docslog{$id}{'logentry'}{'before_resources_'.$idx}))[0];
                   1152: 	    my $newname=(split(/\:/,$docslog{$id}{'logentry'}{'after_resources_'.$idx}))[0];
1.279     albertel 1153: 	    if ($oldname ne '' && $oldname ne $newname) {
1.252     www      1154: 		$r->print(&LONCAPA::map::qtescape($newname));
1.251     www      1155: 	    }
                   1156: 	}        
1.252     www      1157: 	$r->print('<ul>');
                   1158: 	for (my $idx=0;$idx<=$docslog{$id}{'logentry'}{'maxidx'};$idx++) {
                   1159:             if ($docslog{$id}{'logentry'}{'after_order_res_'.$idx}) {
                   1160: 		$r->print('<li>'.&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'after_order_res_'.$idx}))[0]).'</li>');
                   1161: 	    }
                   1162: 	}
                   1163: 	$r->print('</ul>');
                   1164: 	if ($docslog{$id}{'logentry'}{'parameter_res'}) {
                   1165: 	    $r->print(&LONCAPA::map::qtescape((split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'}))[0]).':<ul>');
1.253     www      1166: 	    foreach my $parameter ('randompick','hiddenresource','encrypturl') {
1.252     www      1167: 		if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
1.254     albertel 1168: 		    $r->print('<li>'.
                   1169: 			      &mt($lt{$parameter}.' '.$lt{$docslog{$id}{'logentry'}{'parameter_action_'.$parameter}}.' [_1]',
                   1170: 				  $docslog{$id}{'logentry'}{'parameter_value_'.$parameter})
                   1171: 			      .'</li>');
1.252     www      1172: 		}
                   1173: 	    }
                   1174: 	    $r->print('</ul>');
                   1175: 	}
1.251     www      1176: # End
                   1177:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.247     www      1178:         $shown++;
                   1179:         if (!($env{'form.show'} eq &mt('all')
                   1180:               || $shown<=$env{'form.show'})) { last; }
                   1181:     }
                   1182:     $r->print(&Apache::loncommon::end_data_table());
                   1183: }
                   1184: 
1.281     albertel 1185: sub update_paste_buffer {
                   1186:     my ($coursenum,$coursedom) = @_;
                   1187: 
                   1188:     return if (!defined($env{'form.markcopy'}));
                   1189:     return if (!defined($env{'form.copyfolder'}));
                   1190:     return if ($env{'form.markcopy'} < 0);
                   1191: 
                   1192:     my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                   1193: 				    $env{'form.copyfolder'});
                   1194:     
                   1195:     return if ($fatal);
                   1196: 
                   1197: # Mark for copying
                   1198:     my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]);
                   1199:     if (&is_supplemental_title($title)) {
                   1200: 	($title) = &parse_supplemental_title($title);
                   1201:     }
1.287   ! albertel 1202:     $url=~s{http(&colon;|:)//https(&colon;|:)//}{https$2//};
        !          1203: 
1.281     albertel 1204:     &Apache::lonnet::appenv('docs.markedcopy_title' => $title,
                   1205: 			    'docs.markedcopy_url'   => $url);
                   1206:     delete($env{'form.markcopy'});
                   1207: }
                   1208: 
                   1209: sub print_paste_buffer {
                   1210:     my ($r,$container) = @_;
                   1211:     return if (!defined($env{'docs.markedcopy_url'}));
                   1212: 
                   1213:     $r->print(<<ENDPASTE);
1.286     albertel 1214: <form name="pasteform" action="/adm/coursedocs" method="post"><p>
1.281     albertel 1215: ENDPASTE
                   1216:     $r->print('<input type="submit" name="pastemarked" value="'.&mt('Paste').'" /> ');
                   1217: 
                   1218:     my $type;
1.287   ! albertel 1219:     if ($env{'docs.markedcopy_url'} =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?:&colon;|:))//} ) {
1.281     albertel 1220: 	$type = &mt('External Resource');
1.287   ! albertel 1221: 	$r->print($type.': '.
        !          1222: 		  &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('.
        !          1223: 		  &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')');
1.281     albertel 1224:     }  else {
                   1225: 	my $extension = (split(/\./,$env{'docs.markedcopy_url'}))[-1];
                   1226: 	my $type = &Apache::loncommon::filedescription($extension);
                   1227: 	my $icon = '<img src="'.&Apache::loncommon::icon($extension).
1.286     albertel 1228: 	    '" alt="" class="LC_icon" />';
1.287   ! albertel 1229: 	$r->print($icon.$type.': '.  &parse_supplemental_title(&LONCAPA::map::qtescape($env{'docs.markedcopy_title'})));
1.281     albertel 1230:     }
                   1231:     if ($container eq 'page') {
1.286     albertel 1232: 	$r->print('
                   1233: 	<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />
                   1234: 	<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />
                   1235: ');
1.281     albertel 1236:     } else {
1.286     albertel 1237: 	$r->print('
                   1238:         <input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />
                   1239: ');
1.281     albertel 1240:     }
1.286     albertel 1241:     $r->print('</p></form>');
1.281     albertel 1242: }
                   1243: 
1.7       www      1244: sub editor {
1.281     albertel 1245:     my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$which)=@_;
1.10      www      1246:     my $errtext='';
                   1247:     my $fatal=0;
1.142     raeburn  1248:     my $container='sequence';
1.174     albertel 1249:     if ($env{'form.pagepath'}) {
1.142     raeburn  1250:         $container='page';
                   1251:     }
1.281     albertel 1252:     ($errtext,$fatal) = &mapread($coursenum,$coursedom,$folder.'.'.$container);
1.245     albertel 1253:     if ($#LONCAPA::map::order<1) {
                   1254: 	my $idx=&LONCAPA::map::getresidx();
1.178     www      1255: 	if ($idx<=0) { $idx=1; }
1.245     albertel 1256:        	$LONCAPA::map::order[0]=$idx;
                   1257:         $LONCAPA::map::resources[$idx]='';
1.17      www      1258:     }
1.281     albertel 1259:     
1.251     www      1260:     my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain)=&breadcrumbs($folder);
1.242     www      1261:     $r->print($breadcrumbtrail);
1.7       www      1262:     if ($fatal) {
1.283     albertel 1263: 	   $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.7       www      1264:     } else {
                   1265: # ------------------------------------------------------------ Process commands
1.121     www      1266: 
1.16      www      1267: # ---------------- if they are for this folder and user allowed to make changes
1.174     albertel 1268: 	if (($allowed) && ($env{'form.folder'} eq $folder)) {
1.123     www      1269: # set parameters and change order
1.247     www      1270:             &snapshotbefore();
                   1271: 	    if ($env{'form.changeparms'}) {
1.174     albertel 1272: 		my $idx=$env{'form.setparms'};
1.123     www      1273: # set parameters
1.258     www      1274: 		if ($env{'form.changeparms'} eq 'randompick') {
                   1275: 		    if ($env{'form.randpick_'.$idx}) {
                   1276: 			&LONCAPA::map::storeparameter($idx,'parameter_randompick',$env{'form.randpick_'.$idx},'int_pos');
                   1277: 			&remember_parms($idx,'randompick','set',$env{'form.randpick_'.$idx});
                   1278: 		    } else {
                   1279: 			&LONCAPA::map::delparameter($idx,'parameter_randompick');
                   1280: 			&remember_parms($idx,'randompick','del');
                   1281: 		    }
                   1282: 		}
                   1283: 		if ($env{'form.changeparms'} eq 'hiddenresource') {
                   1284: 		    if ($env{'form.hidprs_'.$idx}) {
                   1285: 			&LONCAPA::map::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno');
                   1286: 			&remember_parms($idx,'hiddenresource','set',$env{'form.hidprs_'.$idx});
                   1287: 		    } else {
                   1288: 			&LONCAPA::map::delparameter($idx,'parameter_hiddenresource');
                   1289: 			&remember_parms($idx,'hiddenresource','del');
                   1290: 		    }
                   1291: 		}
                   1292: 		if ($env{'form.changeparms'} eq 'encrypturl') {
                   1293: 		    if ($env{'form.encprs_'.$idx}) {
                   1294: 			&LONCAPA::map::storeparameter($idx,'parameter_encrypturl','yes','string_yesno');
                   1295: 			&remember_parms($idx,'encrypturl','set',$env{'form.encprs_'.$idx});
                   1296: 		    } else {
                   1297: 			&LONCAPA::map::delparameter($idx,'parameter_encrypturl');
                   1298: 			&remember_parms($idx,'encrypturl','del');
                   1299: 		    }
1.121     www      1300: 		}
1.250     www      1301: # store the changed version
                   1302: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   1303: 		if ($fatal) {
1.283     albertel 1304: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.250     www      1305: 		    return;
                   1306: 		}
1.247     www      1307: 	    }
1.121     www      1308: 
1.247     www      1309: 	    if ($env{'form.newpos'}) {
1.123     www      1310: # change order
1.247     www      1311: 		my $newpos=$env{'form.newpos'}-1;
                   1312: 		my $currentpos=$env{'form.currentpos'}-1;
                   1313: 		my $i;
                   1314: 		my @neworder=();
                   1315: 		if ($newpos>$currentpos) {
1.125     www      1316: # moving stuff up
1.247     www      1317: 		    for ($i=0;$i<$currentpos;$i++) {
                   1318: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1319: 		    }
                   1320: 		    for ($i=$currentpos;$i<$newpos;$i++) {
                   1321: 			$neworder[$i]=$LONCAPA::map::order[$i+1];
                   1322: 		    }
                   1323: 		    $neworder[$newpos]=$LONCAPA::map::order[$currentpos];
                   1324: 		    for ($i=$newpos+1;$i<=$#LONCAPA::map::order;$i++) {
                   1325: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1326: 		    }
                   1327: 		} else {
1.125     www      1328: # moving stuff down
1.247     www      1329: 		    for ($i=0;$i<$newpos;$i++) {
                   1330: 			$neworder[$i]=$LONCAPA::map::order[$i];
                   1331: 		    }
                   1332: 		    $neworder[$newpos]=$LONCAPA::map::order[$currentpos];
                   1333: 		    for ($i=$newpos+1;$i<$currentpos+1;$i++) {
                   1334: 			$neworder[$i]=$LONCAPA::map::order[$i-1];
                   1335: 		    }
                   1336: 		    for ($i=$currentpos+1;$i<=$#LONCAPA::map::order;$i++) {
                   1337: 			$neworder[$i]=$LONCAPA::map::order[$i];
1.125     www      1338: 		    }
1.124     www      1339: 		}
1.247     www      1340: 		@LONCAPA::map::order=@neworder;
1.124     www      1341: # store the changed version
1.142     raeburn  1342: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
1.124     www      1343: 		if ($fatal) {
1.283     albertel 1344: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.124     www      1345: 		    return;
1.123     www      1346: 		}
1.247     www      1347: 	    }
1.281     albertel 1348: 	    
1.174     albertel 1349: 	    if ($env{'form.pastemarked'}) {
1.168     www      1350: # paste resource to end of list
1.287   ! albertel 1351:                 my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'});
        !          1352: 		my $title=&LONCAPA::map::qtescape($env{'docs.markedcopy_title'});
1.168     www      1353: # Maps need to be copied first
                   1354: 		if (($url=~/\.(page|sequence)$/) || ($url=~/^\/uploaded\//)) {
                   1355: 		    $title=&mt('Copy of').' '.$title;
                   1356:                     my $newid=$$.time;
                   1357: 		    $url=~/^(.+)\.(\w+)$/;
                   1358: 		    my $newurl=$1.$newid.'.'.$2;
                   1359: 		    my $storefn=$newurl;
1.264     albertel 1360:                     $storefn=~s{^/\w+/$match_domain/$match_username/}{};
1.244     albertel 1361: 		    &Apache::lonclonecourse::writefile
1.174     albertel 1362: 			($env{'request.course.id'},$storefn,
1.168     www      1363: 			 &Apache::lonnet::getfile($url));
                   1364: 		    $url=$newurl;
                   1365: 		}
1.270     albertel 1366: 		$title = &LONCAPA::map::qtunescape($title);
1.168     www      1367: 		my $ext='false';
1.287   ! albertel 1368: 		if ($url=~m{^http(|s)://}) { $ext='true'; }
1.270     albertel 1369: 		$url   = &LONCAPA::map::qtunescape($url);
1.168     www      1370: # Now insert the URL at the bottom
1.245     albertel 1371:                 my $newidx=&LONCAPA::map::getresidx($url);
                   1372: 		$LONCAPA::map::resources[$newidx]=
1.168     www      1373: 		    $title.':'.$url.':'.$ext.':normal:res';
1.245     albertel 1374: 		$LONCAPA::map::order[1+$#LONCAPA::map::order]=$newidx;
1.168     www      1375: # Store the result
                   1376: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container);
                   1377: 		if ($fatal) {
1.283     albertel 1378: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.168     www      1379: 		    return;
                   1380: 		}
1.123     www      1381: 
1.168     www      1382: 	    }
1.188     raeburn  1383:             $r->print($upload_output);
1.174     albertel 1384: 	    if ($env{'form.cmd'}) {
                   1385:                 my ($cmd,$idx)=split(/\_/,$env{'form.cmd'});
1.10      www      1386:                 if ($cmd eq 'del') {
1.245     albertel 1387: 		    my (undef,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
1.187     www      1388: 		    if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) &&
1.206     albertel 1389: 			($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) {
1.187     www      1390: 			&Apache::lonnet::removeuploadedurl($url);
                   1391: 		    } else {
1.245     albertel 1392: 			&LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
1.128     albertel 1393: 		    }
1.245     albertel 1394: 		    for (my $i=$idx;$i<$#LONCAPA::map::order;$i++) {
                   1395:                         $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
1.10      www      1396:                     }
1.245     albertel 1397:                     $#LONCAPA::map::order--;
1.171     www      1398:                 } elsif ($cmd eq 'cut') {
1.245     albertel 1399: 		    my (undef,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
                   1400: 		    &LONCAPA::map::makezombie($LONCAPA::map::order[$idx]);
                   1401: 		    for (my $i=$idx;$i<$#LONCAPA::map::order;$i++) {
                   1402:                         $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1];
1.171     www      1403:                     }
1.245     albertel 1404:                     $#LONCAPA::map::order--;
1.10      www      1405:                 } elsif ($cmd eq 'up') {
1.245     albertel 1406: 		  if (($idx) && (defined($LONCAPA::map::order[$idx-1]))) {
                   1407:                     my $i=$LONCAPA::map::order[$idx-1];
                   1408:                     $LONCAPA::map::order[$idx-1] = $LONCAPA::map::order[$idx];
                   1409:                     $LONCAPA::map::order[$idx] = $i;
1.38      www      1410: 		   }
1.10      www      1411:                 } elsif ($cmd eq 'down') {
1.245     albertel 1412: 		   if (defined($LONCAPA::map::order[$idx+1])) {
                   1413:                     my $i=$LONCAPA::map::order[$idx+1];
                   1414:                     $LONCAPA::map::order[$idx+1] = $LONCAPA::map::order[$idx];
                   1415:                     $LONCAPA::map::order[$idx] = $i;
1.38      www      1416: 		   }
1.36      www      1417:                 } elsif ($cmd eq 'rename') {
1.245     albertel 1418:                     my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
1.36      www      1419:                     my ($rtitle,@rrest)=split(/\:/,
1.245     albertel 1420:                        $LONCAPA::map::resources[$LONCAPA::map::order[$idx]]);
1.270     albertel 1421:                     my $comment=$env{'form.title'};
                   1422:                     $comment = &LONCAPA::map::qtunescape($comment);
1.144     albertel 1423: 		    if ($comment=~/\S/) {
1.245     albertel 1424: 			$LONCAPA::map::resources[$LONCAPA::map::order[$idx]]=
                   1425: 			    $comment.':'.join(':',@rrest);
1.144     albertel 1426: 		    }
1.238     www      1427: # Devalidate title cache
1.270     albertel 1428:                     my $renamed_url=&LONCAPA::map::qtescape($rrest[0]);
1.240     www      1429: 		    &Apache::lonnet::devalidate_title_cache($renamed_url);
1.10      www      1430:                 }
                   1431: # Store the changed version
1.104     albertel 1432: 		($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.142     raeburn  1433: 					    $folder.'.'.$container);
1.104     albertel 1434: 		if ($fatal) {
1.283     albertel 1435: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.104     albertel 1436: 		    return;
                   1437: 		}
1.8       www      1438:             }
1.11      www      1439: # Group import/search
1.174     albertel 1440: 	    if ($env{'form.importdetail'}) {
1.73      bowersj2 1441: 		my @imports;
1.174     albertel 1442: 		foreach (split(/\&/,$env{'form.importdetail'})) {
1.73      bowersj2 1443: 		    if (defined($_)) {
1.287   ! albertel 1444: 			my ($name,$url,$residx)=
        !          1445: 			    map {&unescape($_)} split(/\=/,$_);
        !          1446: 			push(@imports, [$name, $url, $residx]);
1.73      bowersj2 1447: 		    }
                   1448: 		}
1.11      www      1449: # Store the changed version
1.249     www      1450: 		($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder,
1.142     raeburn  1451: 					       $container,'londocs',@imports);
1.104     albertel 1452: 		if ($fatal) {
1.283     albertel 1453: 		    $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.104     albertel 1454: 		    return;
                   1455: 		}
1.11      www      1456:             }
1.53      www      1457: # Loading a complete map
1.223     www      1458: 	   if ($env{'form.loadmap'}) {
                   1459:                if ($env{'form.importmap'}=~/\w/) {
                   1460: 	          foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
                   1461: 		      my ($title,$url,$ext,$type)=split(/\:/,$_);
1.245     albertel 1462:                       my $idx=&LONCAPA::map::getresidx($url);
                   1463:                       $LONCAPA::map::resources[$idx]=$_;
                   1464:                       $LONCAPA::map::order[$#LONCAPA::map::order+1]=$idx;
1.223     www      1465: 	          }
1.53      www      1466: # Store the changed version
1.223     www      1467:   	          ($errtext,$fatal)=&storemap($coursenum,$coursedom,
1.142     raeburn  1468: 					   $folder.'.'.$container);
1.223     www      1469: 	          if ($fatal) {
1.283     albertel 1470: 		      $r->print('<p><span class="LC_error">'.$errtext.'</span></p>');
1.223     www      1471: 		      return;
                   1472: 	          }
                   1473:                } else {
1.283     albertel 1474: 		    $r->print('<p><span class="LC_error">'.&mt('No map selected.').'</span></p>');
                   1475: 
1.223     www      1476:                }
1.53      www      1477:            }
1.251     www      1478:            &log_differences($plain);
1.281     albertel 1479: 	}
1.16      www      1480: # ---------------------------------------------------------------- End commands
1.7       www      1481: # ---------------------------------------------------------------- Print screen
1.10      www      1482:         my $idx=0;
1.148     www      1483: 	my $shown=0;
1.242     www      1484:         if (($ishidden) || ($isencrypted) || ($randompick>=0)) {
                   1485:            $r->print('<p>'.&mt('Parameters').':<ul>'.
                   1486:                      ($randompick>=0?'<li>'.&mt('randomly pick [_1] resources',$randompick).'</li>':'').
                   1487:                      ($ishidden?'<li>'.&mt('contents hidden').'</li>':'').
                   1488:                      ($isencrypted?'<li>'.&mt('URLs hidden').'</li>':'').
                   1489:                      '</ul></p>');
                   1490:         }                                                                                                     
                   1491:         if ($randompick>=0) {
                   1492:            $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>');
                   1493:         }
1.285     albertel 1494:         $r->print('<table class="LC_docs_editor">');
1.278     albertel 1495:         foreach my $res (@LONCAPA::map::order) {
                   1496:            my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
1.246     raeburn  1497: 	   $name=&LONCAPA::map::qtescape($name);
1.271     albertel 1498: 	   $url=&LONCAPA::map::qtescape($url);
1.10      www      1499:            unless ($name) {  $name=(split(/\//,$url))[-1]; }
1.148     www      1500:            unless ($name) { $idx++; next; }
1.278     albertel 1501:            $r->print(&entryline($idx,$name,$url,$folder,$allowed,$res,
                   1502: 				$coursenum));
1.10      www      1503:            $idx++;
1.148     www      1504: 	   $shown++;
1.10      www      1505:         }
1.148     www      1506: 	unless ($shown) {
1.131     www      1507: 	    $r->print('<tr><td>'.&mt('Currently no documents.').'</td></tr>');
                   1508: 	}
1.168     www      1509:         $r->print("\n</table>\n");
1.278     albertel 1510: 
1.281     albertel 1511: 	&print_paste_buffer($r,$container);
                   1512: 
1.7       www      1513:     }
                   1514: }
1.1       www      1515: 
1.188     raeburn  1516: sub process_file_upload {
1.194     raeburn  1517:     my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
1.188     raeburn  1518: # upload a file, if present
                   1519:     my $parseaction;
1.190     albertel 1520:    if ($env{'form.parserflag'}) {
1.188     raeburn  1521:         $parseaction = 'parse';
                   1522:     }
                   1523:     my $phase_status;
                   1524:     my $folder=$env{'form.folder'};
1.194     raeburn  1525:     if ($folder eq '') {
1.188     raeburn  1526:         $folder='default';
                   1527:     }
1.194     raeburn  1528:     if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
1.188     raeburn  1529:         my $errtext='';
                   1530:         my $fatal=0;
                   1531:         my $container='sequence';
                   1532:         if ($env{'form.pagepath'}) {
                   1533:             $container='page';
                   1534:         }
                   1535:         ($errtext,$fatal)=
                   1536:               &mapread($coursenum,$coursedom,$folder.'.'.$container);
1.245     albertel 1537:         if ($#LONCAPA::map::order<1) {
                   1538:             $LONCAPA::map::order[0]=1;
                   1539:             $LONCAPA::map::resources[1]='';
1.188     raeburn  1540:         }
                   1541:         if ($fatal) {
                   1542:             return 'failed';
                   1543:         }
                   1544:         my $destination = 'docs/';
1.194     raeburn  1545:         if ($folder =~ /^supplemental/) {
                   1546:             $destination = 'supplemental/';
                   1547:         }
                   1548:         if (($folder eq 'default') || ($folder eq 'supplemental')) {
1.188     raeburn  1549:             $destination .= 'default/';
1.194     raeburn  1550:         } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
                   1551:             $destination .=  $2.'/';
1.188     raeburn  1552:         }
                   1553: # this is for a course, not a user, so set coursedoc flag
                   1554: # probably the only place in the system where this should be "1"
1.245     albertel 1555:         my $newidx=&LONCAPA::map::getresidx();
1.188     raeburn  1556:         $destination .= $newidx;
1.190     albertel 1557:         my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination,
                   1558: 						$parseaction,$allfiles,
                   1559: 						$codebase);
1.188     raeburn  1560:         my $ext='false';
1.287   ! albertel 1561:         if ($url=~m{^http://}) { $ext='true'; }
1.270     albertel 1562: 	$url     = &LONCAPA::map::qtunescape($url);
1.188     raeburn  1563:         my $comment=$env{'form.comment'};
1.270     albertel 1564: 	$comment = &LONCAPA::map::qtunescape($comment);
1.188     raeburn  1565:         if ($folder=~/^supplemental/) {
                   1566:               $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
                   1567:                   $env{'user.domain'}.'___&&&___'.$comment;
                   1568:         }
                   1569: 
1.245     albertel 1570:         $LONCAPA::map::resources[$newidx]=
                   1571: 	    $comment.':'.$url.':'.$ext.':normal:res';
                   1572:         $LONCAPA::map::order[$#LONCAPA::map::order+1]= $newidx;
1.190     albertel 1573:         ($errtext,$fatal)=&storemap($coursenum,$coursedom,
                   1574: 				    $folder.'.'.$container);
1.188     raeburn  1575:         if ($fatal) {
1.283     albertel 1576:             $$upload_output .= '<p><span class="LC_error">'.$errtext.'</span></p>';
1.188     raeburn  1577:             return 'failed';
                   1578:         } else {
                   1579:             if ($parseaction eq 'parse') {
1.190     albertel 1580:                 my $total_embedded = keys(%{$allfiles});
1.188     raeburn  1581:                 if ($total_embedded > 0) {
                   1582:                     my $num = 0;
1.269     albertel 1583: 		    my $state = '
1.282     albertel 1584:    <input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />
1.269     albertel 1585:    <input type="hidden" name="cmd" value="upload_embedded" />
1.188     raeburn  1586:    <input type="hidden" name="newidx" value="'.$newidx.'" />
1.228     www      1587:    <input type="hidden" name="primaryurl" value="'.&escape($url).'" />
1.188     raeburn  1588:    <input type="hidden" name="phasetwo" value="'.$total_embedded.'" />';
1.269     albertel 1589: 		    $phase_status = 'phasetwo';
                   1590: 
                   1591:                     $$upload_output .= 
                   1592: 			'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br />'.
                   1593: 			&ask_for_embedded_content('/adm/coursedocs',
                   1594: 						  $state,$allfiles,$codebase);
1.188     raeburn  1595:                 } else {
                   1596:                     $$upload_output .= 'No embedded items identified<br />';
                   1597:                 }
                   1598:             }
                   1599:         }
                   1600:     }
                   1601:     return $phase_status;
                   1602: }
                   1603: 
1.269     albertel 1604: sub ask_for_embedded_content {
1.271     albertel 1605:     my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
1.269     albertel 1606:     my $upload_output = '
                   1607:    <form name="upload_embedded" action="'.$actionurl.'"
                   1608:                   method="post" enctype="multipart/form-data">';
                   1609:     $upload_output .= $state;
1.271     albertel 1610:     $upload_output .= '<b>Upload embedded files</b>:<br />'.
                   1611: 	&Apache::loncommon::start_data_table();
1.269     albertel 1612: 
                   1613:     my $num = 0;
1.276     albertel 1614:     foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) {
1.271     albertel 1615: 	$upload_output .= &Apache::loncommon::start_data_table_row().
                   1616: 	    '<td>'.$embed_file.'</td><td>';
1.274     albertel 1617: 	if ($args->{'ignore_remote_references'}
                   1618: 	    && $embed_file =~ m{^\w+://}) {
                   1619: 	    $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
                   1620: 	} elsif ($args->{'error_on_invalid_names'}
1.271     albertel 1621: 	    && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
                   1622: 	    
                   1623: 	    $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';
1.274     albertel 1624: 	    
1.271     albertel 1625: 	} else {
1.274     albertel 1626: 
1.271     albertel 1627: 	    $upload_output .='
1.269     albertel 1628:            <input name="embedded_item_'.$num.'" type="file" value="bob" />
                   1629:            <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
1.271     albertel 1630: 	    my $attrib = join(':',@{$$allfiles{$embed_file}});
                   1631: 	    $upload_output .=
1.269     albertel 1632: 		"\n\t\t".
1.271     albertel 1633: 		'<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
                   1634: 		$attrib.'" />';
                   1635: 	    if (exists($$codebase{$embed_file})) {
                   1636: 		$upload_output .= 
                   1637: 		    "\n\t\t".
                   1638: 		    '<input name="codebase_'.$num.'" type="hidden" value="'.
                   1639: 		    &escape($$codebase{$embed_file}).'" />';
                   1640: 	    }
1.269     albertel 1641: 	}
1.271     albertel 1642: 	$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();
1.269     albertel 1643: 	$num++;
                   1644:     }
1.271     albertel 1645:     $upload_output .= &Apache::loncommon::end_data_table().'<br />
1.269     albertel 1646:    <input type ="hidden" name="number_embedded_items" value="'.$num.'" />
1.275     albertel 1647:    <input type ="submit" value="'.&mt('Upload Listed Files').'" />
                   1648:    '.&mt('(only files for which a location has been provided will be uploaded)').'
1.269     albertel 1649:    </form>';
                   1650:     return $upload_output;
                   1651: }
                   1652: 
1.188     raeburn  1653: sub process_secondary_uploads {
                   1654:     my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
                   1655:     my $folder=$env{'form.folder'};
                   1656:     my $destination = 'docs/';
1.195     raeburn  1657:     if ($folder =~ /^supplemental/) {
                   1658:         $destination = 'supplemental/';
                   1659:     }
                   1660:     if (($folder eq 'default') || ($folder eq 'supplemental')) {
1.188     raeburn  1661:         $destination .= 'default/';
1.195     raeburn  1662:     } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
1.217     raeburn  1663:         $destination .=  $2.'/';
1.188     raeburn  1664:     }
                   1665:     $destination .= $newidx;
                   1666:     my ($url,$filename);
                   1667:     $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination);
1.265     albertel 1668:     ($filename) = ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/\Q$destination\E/(.+)$});
1.188     raeburn  1669:     return $filename;
                   1670: }
                   1671: 
1.281     albertel 1672: sub is_supplemental_title {
                   1673:     my ($title) = @_;
                   1674:     return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
                   1675: }
                   1676: 
                   1677: sub parse_supplemental_title {
                   1678:     my ($title) = @_;
                   1679: 
                   1680:     my ($foldertitle,$renametitle);
                   1681:     if ($title =~ /&amp;&amp;&amp;/) {
                   1682: 	$title = &HTML::Entites::decode($title);
                   1683:     }
                   1684:  if ($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/) {
                   1685: 	$renametitle=$4;
                   1686: 	my ($time,$uname,$udom) = ($1,$2,$3);
                   1687: 	$foldertitle=&Apache::lontexconvert::msgtexconverted($4);
                   1688: 	my $name =  &Apache::loncommon::plainname($uname,$udom);
                   1689: 	$name = &HTML::Entities::encode($name,'"<>&\'');
                   1690: 	$title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.
                   1691: 	    $name.': <br />'.$foldertitle;
                   1692:     }
                   1693:     if (wantarray) {
                   1694: 	return ($title,$foldertitle,$renametitle);
                   1695:     } 
                   1696:     return $title;
                   1697: }
                   1698: 
1.8       www      1699: # --------------------------------------------------------------- An entry line
                   1700: 
                   1701: sub entryline {
1.112     raeburn  1702:     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_;
1.281     albertel 1703: 
                   1704:     my ($foldertitle,$pagetitle,$renametitle);
                   1705:     if (&is_supplemental_title($title)) {
                   1706: 	($title,$foldertitle,$renametitle) = &parse_supplemental_title($title);
                   1707: 	$pagetitle = $foldertitle;
                   1708:     } else {
                   1709: 	$title=&HTML::Entities::encode($title,'"<>&\'');
                   1710: 	$renametitle=$title;
                   1711: 	$foldertitle=$title;
                   1712: 	$pagetitle=$title;
                   1713:     }
                   1714: 
1.245     albertel 1715:     my $orderidx=$LONCAPA::map::order[$index];
1.281     albertel 1716:     
                   1717: 
1.222     albertel 1718:     $renametitle=~s/\\/\\\\/g;
1.38      www      1719:     $renametitle=~s/\&quot\;/\\\"/g;
1.286     albertel 1720:     $renametitle=~s/ /%20/g;
1.8       www      1721:     my $line='<tr>';
1.286     albertel 1722:     my ($form_start,$form_end);
1.8       www      1723: # Edit commands
1.142     raeburn  1724:     my $container;
1.280     albertel 1725:     my ($container, $type, $esc_path, $path, $symb);
1.174     albertel 1726:     if ($env{'form.folderpath'}) {
1.280     albertel 1727: 	$type = 'folder';
1.142     raeburn  1728:         $container = 'sequence';
1.282     albertel 1729: 	$esc_path=&escape($env{'form.folderpath'});
                   1730: 	$path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.174     albertel 1731: 	# $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"');
1.120     www      1732:     }
1.174     albertel 1733:     if ($env{'form.pagepath'}) {
1.280     albertel 1734:         $type = $container = 'page';
                   1735:         $esc_path=&escape($path = $env{'form.pagepath'});
1.282     albertel 1736: 	$path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"');
1.280     albertel 1737:         $symb=&escape($env{'form.pagesymb'});
1.142     raeburn  1738:     }
1.168     www      1739:     my $cpinfo='';
1.109     albertel 1740:     if ($allowed) {
1.123     www      1741: 	my $incindex=$index+1;
                   1742: 	my $selectbox='';
1.168     www      1743: 	if (($folder!~/^supplemental/) &&
1.245     albertel 1744: 	    ($#LONCAPA::map::order>0) && 
1.168     www      1745: 	    ((split(/\:/,
1.245     albertel 1746: 	     $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1] 
1.168     www      1747: 	     ne '') && 
                   1748: 	    ((split(/\:/,
1.245     albertel 1749: 	     $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1] 
1.168     www      1750: 	     ne '')) {
1.123     www      1751: 	    $selectbox=
1.124     www      1752: 		'<input type="hidden" name="currentpos" value="'.$incindex.'" />'.
1.123     www      1753: 		'<select name="newpos" onChange="this.form.submit()">';
1.245     albertel 1754: 	    for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) {
1.123     www      1755: 		if ($i==$incindex) {
                   1756: 		    $selectbox.='<option value="" selected="1">('.$i.')</option>';
                   1757: 		} else {
                   1758: 		    $selectbox.='<option value="'.$i.'">'.$i.'</option>';
                   1759: 		}
                   1760: 	    }
                   1761: 	    $selectbox.='</select>';
                   1762: 	}
1.119     www      1763: 	my %lt=&Apache::lonlocal::texthash(
                   1764:                 'up' => 'Move Up',
1.109     albertel 1765: 		'dw' => 'Move Down',
                   1766: 		'rm' => 'Remove',
1.171     www      1767:                 'ct' => 'Cut',
1.168     www      1768: 		'rn' => 'Rename',
                   1769: 		'cp' => 'Copy');
1.211     www      1770: 	my $nocopy=0;
1.268     www      1771:         my $nocut=0;
1.211     www      1772:         if ($url=~/\.(page|sequence)$/) {
                   1773: 	    foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url))) {
                   1774: 		my ($title,$url,$ext,$type)=split(/\:/,$_);
                   1775: 		if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) {
                   1776: 		    $nocopy=1;
                   1777: 		    last;
                   1778: 		}
                   1779: 	    }
                   1780: 	}
1.268     www      1781:         if ($url=~/^\/res\/lib\/templates\//) { 
                   1782:            $nocopy=1; 
                   1783:            $nocut=1;
                   1784:         }
1.211     www      1785:         my $copylink='&nbsp;';
1.267     www      1786:         my $cutlink='&nbsp;';
1.280     albertel 1787: 	
                   1788: 	if (!$nocopy) {
                   1789: 	    $copylink=(<<ENDCOPY);
1.284     albertel 1790: <a href='javascript:markcopy("$esc_path","$index","$renametitle","$container","$symb","$folder");' class="LC_docs_copy">$lt{'cp'}</a>
1.211     www      1791: ENDCOPY
1.280     albertel 1792:         }
                   1793: 	if (!$nocut) {
                   1794: 	    $cutlink=(<<ENDCUT);
1.284     albertel 1795: <a href='javascript:cutres("$esc_path","$index","$renametitle","$container","$symb","$folder");' class="LC_docs_cut">$lt{'ct'}</a>
1.267     www      1796: ENDCUT
1.280     albertel 1797:         }
1.286     albertel 1798: 	$form_start = (<<END);
                   1799:    <form  action="/adm/coursedocs" method="post">
1.280     albertel 1800:    <input type="hidden" name="${type}path" value="$path" />
                   1801:    <input type="hidden" name="${type}symb" value="$symb" />
                   1802:    <input type="hidden" name="setparms" value="$orderidx" />
                   1803:    <input type="hidden" name="changeparms" value="0" />
1.286     albertel 1804: END
                   1805:         $form_end = '</form>';
                   1806: 	$line.=(<<END);
1.280     albertel 1807: <td>
1.285     albertel 1808:    <table class="LC_docs_entry_move">
1.280     albertel 1809:       <tr>
1.285     albertel 1810:          <td>
1.282     albertel 1811:             <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 1812:          </td>
                   1813:       </tr>
                   1814:       <tr>
1.285     albertel 1815:         <td>
1.282     albertel 1816:            <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 1817:         </td>
                   1818:       </tr>
                   1819:     </table>
                   1820: </td>
                   1821: <td>
1.286     albertel 1822:    $form_start
1.280     albertel 1823:    $selectbox
1.286     albertel 1824:    $form_end
1.280     albertel 1825: </td>
1.285     albertel 1826: <td class="LC_docs_entry_commands">
1.284     albertel 1827:    <a href='javascript:removeres("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_remove">$lt{'rm'}</a>
1.267     www      1828: $cutlink
1.284     albertel 1829:    <a href='javascript:changename("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_rename">$lt{'rn'}</a>
1.211     www      1830: $copylink
1.280     albertel 1831: </td>
1.142     raeburn  1832: END
1.280     albertel 1833: 
1.8       www      1834:     }
1.16      www      1835: # Figure out what kind of a resource this is
                   1836:     my ($extension)=($url=~/\.(\w+)$/);
                   1837:     my $uploaded=($url=~/^\/*uploaded\//);
1.97      albertel 1838:     my $icon=&Apache::loncommon::icon($url);
1.17      www      1839:     my $isfolder=0;
1.142     raeburn  1840:     my $ispage=0;
1.114     albertel 1841:     my $folderarg;
1.142     raeburn  1842:     my $pagearg;
                   1843:     my $pagefile;
1.16      www      1844:     if ($uploaded) {
1.135     albertel 1845: 	if ($extension eq 'sequence') {
                   1846: 	    $icon=$iconpath.'/folder_closed.gif';
1.264     albertel 1847: 	    $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
1.135     albertel 1848: 	    $url='/adm/coursedocs?';
                   1849: 	    $folderarg=$1;
                   1850: 	    $isfolder=1;
1.142     raeburn  1851:         } elsif ($extension eq 'page') {
                   1852:             $icon=$iconpath.'/page.gif';
1.264     albertel 1853:             $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
1.142     raeburn  1854:             $pagearg=$1;
                   1855:             $url='/adm/coursedocs?';
                   1856:             $ispage=1;
1.135     albertel 1857: 	} else {
                   1858: 	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
                   1859: 	}
1.16      www      1860:     }
1.287   ! albertel 1861:     
        !          1862:     my $orig_url = $url;
        !          1863:     my $external = ($url=~s{^http(|s)(&colon;|:)//}{/adm/wrapper/ext/});
1.142     raeburn  1864:     if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) {
1.113     albertel 1865: 	my $symb=&Apache::lonnet::symbclean(
1.50      www      1866:           &Apache::lonnet::declutter('uploaded/'.
1.174     albertel 1867:            $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
                   1868:            $env{'course.'.$env{'request.course.id'}.'.num'}.'/'.$folder.
1.50      www      1869:            '.sequence').
                   1870:            '___'.$residx.'___'.
1.113     albertel 1871: 	   &Apache::lonnet::declutter($url));
                   1872: 	(undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
                   1873: 	$url=&Apache::lonnet::clutter($url);
1.127     albertel 1874: 	if ($url=~/^\/*uploaded\//) {
                   1875: 	    $url=~/\.(\w+)$/;
                   1876: 	    my $embstyle=&Apache::loncommon::fileembstyle($1);
                   1877: 	    if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
                   1878: 		$url='/adm/wrapper'.$url;
                   1879: 	    } elsif ($embstyle eq 'ssi') {
                   1880: 		#do nothing with these
                   1881: 	    } elsif ($url!~/\.(sequence|page)$/) {
                   1882: 		$url='/adm/coursedocs/showdoc'.$url;
                   1883: 	    }
1.145     albertel 1884: 	} elsif ($url=~m|^/ext/|) { 
                   1885: 	    $url='/adm/wrapper'.$url;
1.287   ! albertel 1886: 	    $external = 1;
1.127     albertel 1887: 	}
1.241     www      1888:         if (&Apache::lonnet::symbverify($symb,$url)) {
                   1889: 	    $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
                   1890:         } else {
                   1891:             $url='';
                   1892:         }
1.152     albertel 1893: 	if ($container eq 'page') {
1.174     albertel 1894: 	    my $symb=$env{'form.pagesymb'};
1.152     albertel 1895: 	    	    
                   1896: 	    $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
1.228     www      1897: 	    $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
1.152     albertel 1898: 	}
1.50      www      1899:     }
1.120     www      1900:     my $parameterset='&nbsp;';
1.216     albertel 1901:     if ($isfolder || $extension eq 'sequence') {
1.228     www      1902: 	my $foldername=&escape($foldertitle);
1.174     albertel 1903: 	my $folderpath=$env{'form.folderpath'};
1.114     albertel 1904: 	if ($folderpath) { $folderpath.='&' };
1.242     www      1905: # Append randompick number, hidden, and encrypted with ":" to foldername, 
                   1906: # so it gets transferred between levels
1.245     albertel 1907: 	$folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx,
1.242     www      1908:                                               'parameter_randompick'))[0]
1.245     albertel 1909:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
1.242     www      1910:                                               'parameter_hiddenresource'))[0]=~/^yes$/i)
1.245     albertel 1911:                                                .':'.((&LONCAPA::map::getparameter($orderidx,
1.242     www      1912:                                               'parameter_encrypturl'))[0]=~/^yes$/i);
1.228     www      1913: 	$url.='folderpath='.&escape($folderpath).$cpinfo;
1.147     matthew  1914: 	$parameterset='<label>'.&mt('Randomly Pick: ').
1.258     www      1915: 	    '<input type="text" size="4" onChange="this.form.changeparms.value='."'randompick'".';this.form.submit()" name="randpick_'.$orderidx.'" value="'.
1.245     albertel 1916: 	    (&LONCAPA::map::getparameter($orderidx,
1.147     matthew  1917:                                               'parameter_randompick'))[0].
1.165     www      1918:                                               '" />'.
1.285     albertel 1919: '<a href="javascript:void(0)">'.&mt('Save').'</a></label>';
1.147     matthew  1920:        
1.114     albertel 1921:     }
1.142     raeburn  1922:     if ($ispage) {
1.228     www      1923:         my $pagename=&escape($pagetitle);
1.142     raeburn  1924:         my $pagepath;
1.174     albertel 1925:         my $folderpath=$env{'form.folderpath'};
1.142     raeburn  1926:         if ($folderpath) { $pagepath = $folderpath.'&' };
                   1927:         $pagepath.=$pagearg.'&'.$pagename;
1.174     albertel 1928: 	my $symb=$env{'form.pagesymb'};
1.152     albertel 1929: 	if (!$symb) {
                   1930: 	    my $path='uploaded/'.
1.174     albertel 1931: 		$env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
                   1932: 		$env{'course.'.$env{'request.course.id'}.'.num'}.'/';
1.152     albertel 1933: 	    $symb=&Apache::lonnet::encode_symb($path.$folder.'.sequence',
                   1934: 					       $residx,
                   1935: 					       $path.$pagearg.'.page');
                   1936: 	}
1.228     www      1937: 	$url.='pagepath='.&escape($pagepath).
1.282     albertel 1938: 	    '&amp;pagesymb='.&escape($symb).$cpinfo;
1.142     raeburn  1939:     }
1.287   ! albertel 1940:     if ($external) {
        !          1941: 	my $form = ($folder =~ /^default/)? 'newext' : 'supnewext';
        !          1942: 	$external = '&nbsp;<a class="LC_docs_ext_edit" href="javascript:edittext(\''.$form.'\',\''.$residx.'\',\''.&escape($title).'\',\''.&escape($orig_url).'\');" >'.&mt('Edit').'</a>';
        !          1943:     } else {
        !          1944: 	undef($external);
        !          1945:     }
1.285     albertel 1946:     $line.='
                   1947:   <td class="LC_docs_entry_icon">
1.287   ! albertel 1948:     '.($url?'<a href="'.$url.'">':'').'<img src="'.$icon.'" alt="" class="LC_icon" />'.($url?'</a>':'').'
1.285     albertel 1949:   </td>
                   1950:   <td class="LC_docs_entry_title">
1.287   ! albertel 1951:     '.($url?"<a href=\"$url\">":'').$title.($url?'</a>':' <span class="LC_docs_reinit_warn">'.&mt('(re-initialize course to access)').'</span>').$external."
1.285     albertel 1952:   </td>";
1.120     www      1953:     if (($allowed) && ($folder!~/^supplemental/)) {
                   1954:  	my %lt=&Apache::lonlocal::texthash(
                   1955:  			      'hd' => 'Hidden',
1.165     www      1956:  			      'ec' => 'URL hidden');
1.122     www      1957: 	my $enctext=
1.245     albertel 1958: 	    ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':'');
1.122     www      1959: 	my $hidtext=
1.245     albertel 1960: 	    ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':'');
1.120     www      1961: 	$line.=(<<ENDPARMS);
1.285     albertel 1962:   <td class="LC_docs_entry_parameter">
1.286     albertel 1963:     $form_start
1.285     albertel 1964:     <label><input type="checkbox" name="hidprs_$orderidx" onClick="this.form.changeparms.value='hiddenresource';this.form.submit()" $hidtext /> $lt{'hd'}</label>
1.286     albertel 1965:     $form_end
1.285     albertel 1966:   </td>
                   1967:   <td class="LC_docs_entry_parameter">
1.286     albertel 1968:     $form_start
1.285     albertel 1969:     <label><input type="checkbox" name="encprs_$orderidx" onClick="this.form.changeparms.value='encrypturl';this.form.submit()" $enctext /> $lt{'ec'}</label>
1.286     albertel 1970:     $form_end
1.285     albertel 1971:   </td>
1.286     albertel 1972:   <td class="LC_docs_entry_parameter">$form_start $parameterset $form_end</td>
1.120     www      1973: ENDPARMS
1.119     www      1974:     }
1.286     albertel 1975:     $line.="</tr>";
1.8       www      1976:     return $line;
                   1977: }
                   1978: 
1.27      www      1979: # ---------------------------------------------------------------- tie the hash
                   1980: 
                   1981: sub tiehash {
1.136     albertel 1982:     my ($mode)=@_;
1.27      www      1983:     $hashtied=0;
1.174     albertel 1984:     if ($env{'request.course.fn'}) {
1.136     albertel 1985: 	if ($mode eq 'write') {
1.174     albertel 1986: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136     albertel 1987: 		    &GDBM_WRCREAT(),0640)) {
                   1988:                 $hashtied=2;
                   1989: 	    }
                   1990: 	} else {
1.174     albertel 1991: 	    if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136     albertel 1992: 		    &GDBM_READER(),0640)) {
1.27      www      1993:                 $hashtied=1;
1.136     albertel 1994: 	    }
                   1995: 	}
1.27      www      1996:     }    
                   1997: }
                   1998: 
                   1999: sub untiehash {
                   2000:     if ($hashtied) { untie %hash; }
                   2001:     $hashtied=0;
1.221     albertel 2002:     return OK;
1.27      www      2003: }
                   2004: 
1.29      www      2005: # --------------------------------------------------------------- check on this
                   2006: 
                   2007: sub checkonthis {
                   2008:     my ($r,$url,$level,$title)=@_;
1.228     www      2009:     $url=&unescape($url);
1.29      www      2010:     $alreadyseen{$url}=1;
                   2011:     $r->rflush();
1.41      www      2012:     if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
1.108     albertel 2013:        $r->print("\n<br />");
1.29      www      2014:        for (my $i=0;$i<=$level*5;$i++) {
                   2015:            $r->print('&nbsp;');
                   2016:        }
                   2017:        $r->print('<a href="'.$url.'" target="cat">'.
                   2018: 		 ($title?$title:$url).'</a> ');
                   2019:        if ($url=~/^\/res\//) {
                   2020: 	  my $result=&Apache::lonnet::repcopy(
                   2021:                               &Apache::lonnet::filelocation('',$url));
1.172     raeburn  2022:           if ($result eq 'ok') {
1.87      www      2023:              $r->print('<font color="green">'.&mt('ok').'</font>');
1.29      www      2024:              $r->rflush();
1.34      www      2025:              &Apache::lonnet::countacc($url);
                   2026:              $url=~/\.(\w+)$/;
                   2027:              if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
                   2028: 		 $r->print('<br />');
                   2029:                  $r->rflush();
                   2030:                  for (my $i=0;$i<=$level*5;$i++) {
                   2031:                      $r->print('&nbsp;');
                   2032:                  }
1.84      www      2033:                  $r->print('- '.&mt('Rendering').': ');
1.170     www      2034: 		 my ($errorcount,$warningcount)=split(/:/,
                   2035: 	       &Apache::lonnet::ssi_body($url,
1.173     albertel 2036: 			       ('grade_target'=>'web',
                   2037: 				'return_only_error_and_warning_counts' => 1)));
1.170     www      2038:                  if (($errorcount) ||
                   2039:                      ($warningcount)) {
                   2040: 		     if ($errorcount) {
1.283     albertel 2041:                         $r->print('<img src="/adm/lonMisc/bomb.gif" /><span class="LC_error">'.
1.170     www      2042: 			  $errorcount.' '.
1.283     albertel 2043: 				  &mt('error(s)').'</span> ');
1.34      www      2044:                      }
1.170     www      2045: 		     if ($warningcount) {
1.283     albertel 2046:                         $r->print('<span class="LC_warning">'.
1.170     www      2047: 			  $warningcount.' '.
1.283     albertel 2048: 				  &mt('warning(s)').'</span>');
1.34      www      2049:                      }
                   2050:                  } else {
1.283     albertel 2051:                      $r->print('<span class="LC_success">'.&mt('ok').'</span>');
1.34      www      2052:                  }
                   2053:                  $r->rflush();
                   2054:              }
1.29      www      2055: 	     my $dependencies=
                   2056:                 &Apache::lonnet::metadata($url,'dependencies');
                   2057:              foreach (split(/\,/,$dependencies)) {
                   2058: 		 if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
                   2059:                     &checkonthis($r,$_,$level+1);
                   2060:                  }
                   2061:              }
1.172     raeburn  2062:           } elsif ($result eq 'unavailable') {
1.283     albertel 2063:              $r->print('<span class="LC_error">'.&mt('connection down').'</span>');
1.172     raeburn  2064:           } elsif ($result eq 'not_found') {
1.100     www      2065: 	      unless ($url=~/\$/) {
1.283     albertel 2066: 		  $r->print('<span class="LC_error">'.&mt('not found').'</b></font>');
1.100     www      2067: 	      } else {
1.283     albertel 2068: 		  $r->print('<span class="LC_unknown">'.&mt('unable to verify variable URL').'</span>');
1.100     www      2069: 	      }
1.29      www      2070:           } else {
1.283     albertel 2071:              $r->print('<span class="LC_error">'.&mt('access denied').'</span>');
1.29      www      2072:           }
                   2073:       }
                   2074:    }
                   2075: }
                   2076: 
1.1       www      2077: 
1.75      www      2078: #
1.208     albertel 2079: # ----------------------------------------------------------------- List Symbs
                   2080: # 
                   2081: sub list_symbs {
1.224     albertel 2082:     my ($r) = @_;
                   2083: 
                   2084:     $r->print(&Apache::loncommon::start_page('Symb List'));
1.257     www      2085:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Symb List'));
1.224     albertel 2086:     my $navmap = Apache::lonnavmaps::navmap->new();
                   2087:     $r->print("<pre>\n");
                   2088:     foreach my $res ($navmap->retrieveResources()) {
                   2089: 	$r->print($res->compTitle()."\t".$res->symb()."\n");
                   2090:     }
                   2091:     $r->print("\n</pre>\n");
                   2092:     $r->print('<a href="/adm/coursedocs">'.&mt('Return to DOCS').'</a>');
1.208     albertel 2093: }
                   2094: 
                   2095: 
                   2096: #
1.75      www      2097: # -------------------------------------------------------------- Verify Content
                   2098: # 
                   2099: sub verifycontent {
1.224     albertel 2100:     my ($r) = @_;
1.230     albertel 2101:     my $type = &Apache::loncommon::course_type();
1.26      www      2102:    my $loaderror=&Apache::lonnet::overloaderror($r);
                   2103:    if ($loaderror) { return $loaderror; }
1.229     raeburn  2104:    $r->print(&Apache::loncommon::start_page('Verify '.$type.' Documents'));
1.257     www      2105:    $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$type.' Documents'));
1.27      www      2106:    $hashtied=0;
1.30      www      2107:    undef %alreadyseen;
                   2108:    %alreadyseen=();
1.27      www      2109:    &tiehash();
                   2110:    foreach (keys %hash) {
1.140     www      2111:        if ($hash{$_}=~/\.(page|sequence)$/) {
1.228     www      2112: 	   if (($_=~/^src_/) && ($alreadyseen{&unescape($hash{$_})})) {
1.283     albertel 2113: 	       $r->print('<hr /><span class="LC_error">'.
1.230     albertel 2114: 			 &mt('The following sequence or page is included more than once in your '.$type.': ').
1.283     albertel 2115: 			 &unescape($hash{$_}).'</span><br />'.
1.140     www      2116: 			 &mt('Note that grading records for problems included in this sequence or folder will overlap.<hr />'));
                   2117: 	   }
                   2118:        }
1.228     www      2119:        if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$_})})) {
1.29      www      2120:            &checkonthis($r,$hash{$_},0,$hash{'title_'.$1});
1.27      www      2121:        }
                   2122:    }
                   2123:    &untiehash();
1.108     albertel 2124:    $r->print('<h1>'.&mt('Done').'.</h1>'.'<a href="/adm/coursedocs">'.
                   2125: 	     &mt('Return to DOCS').'</a>');
1.75      www      2126: }
                   2127: 
1.192     www      2128: 
1.75      www      2129: # -------------------------------------------------------------- Check Versions
                   2130: 
1.192     www      2131: sub devalidateversioncache {
                   2132:     my $src=shift;
                   2133:     &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
                   2134: 					  &Apache::lonnet::clutter($src));
                   2135: }
                   2136: 
1.75      www      2137: sub checkversions {
1.224     albertel 2138:     my ($r) = @_;
1.230     albertel 2139:     my $type = &Apache::loncommon::course_type();
1.229     raeburn  2140:     $r->print(&Apache::loncommon::start_page("Check $type Document Versions"));
1.257     www      2141:     $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $type Document Versions"));
1.89      www      2142:     my $header='';
                   2143:     my $startsel='';
                   2144:     my $monthsel='';
                   2145:     my $weeksel='';
                   2146:     my $daysel='';
                   2147:     my $allsel='';
                   2148:     my %changes=();
                   2149:     my $starttime=0;
1.91      www      2150:     my $haschanged=0;
1.92      www      2151:     my %setversions=&Apache::lonnet::dump('resourceversions',
1.174     albertel 2152: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2153: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
1.92      www      2154: 
                   2155:     $hashtied=0;
                   2156:     &tiehash();
                   2157:     my %newsetversions=();
1.174     albertel 2158:     if ($env{'form.setmostrecent'}) {
1.91      www      2159: 	$haschanged=1;
1.92      www      2160: 	foreach (keys %hash) {
                   2161: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
1.93      www      2162: 		$newsetversions{$1}='mostrecent';
1.192     www      2163:                 &devalidateversioncache($1);
1.92      www      2164: 	    }
                   2165: 	}
1.174     albertel 2166:     } elsif ($env{'form.setcurrent'}) {
1.91      www      2167: 	$haschanged=1;
1.92      www      2168: 	foreach (keys %hash) {
                   2169: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
1.93      www      2170: 		my $getvers=&Apache::lonnet::getversion($1);
                   2171: 		if ($getvers>0) {
                   2172: 		    $newsetversions{$1}=$getvers;
1.192     www      2173: 		    &devalidateversioncache($1);
1.93      www      2174: 		}
1.92      www      2175: 	    }
                   2176: 	}
1.174     albertel 2177:     } elsif ($env{'form.setversions'}) {
1.91      www      2178: 	$haschanged=1;
1.174     albertel 2179: 	foreach (keys %env) {
1.92      www      2180: 	    if ($_=~/^form\.set_version_(.+)$/) {
                   2181: 		my $src=$1;
1.174     albertel 2182: 		if (($env{$_}) && ($env{$_} ne $setversions{$src})) {
                   2183: 		    $newsetversions{$src}=$env{$_};
1.192     www      2184: 		    &devalidateversioncache($src);
1.92      www      2185: 		}
                   2186: 	    }
                   2187: 	}
1.91      www      2188:     }
                   2189:     if ($haschanged) {
1.92      www      2190:         if (&Apache::lonnet::put('resourceversions',\%newsetversions,
1.174     albertel 2191: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2192: 			  $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {		
1.272     albertel 2193: 	    $r->print('<h1>'.&mt('Your Version Settings have been Saved').'</h1>');
1.92      www      2194: 	} else {
1.283     albertel 2195: 	    $r->print('<h1><span class="LC_error">'.&mt('An Error Occured while Attempting to Save your Version Settings').'</span></h1>');
1.92      www      2196: 	}
1.136     albertel 2197: 	&mark_hash_old();
1.91      www      2198:     }
1.136     albertel 2199:     &changewarning($r,'');
1.174     albertel 2200:     if ($env{'form.timerange'} eq 'all') {
1.89      www      2201: # show all documents
1.230     albertel 2202: 	$header=&mt('All Documents in '.$type);
1.91      www      2203: 	$allsel=1;
1.90      www      2204: 	foreach (keys %hash) {
                   2205: 	    if ($_=~/^ids\_(\/res\/.+)$/) {
                   2206: 		my $src=$1;
                   2207: 		$changes{$src}=1;
                   2208: 	    }
                   2209: 	}
1.89      www      2210:     } else {
                   2211: # show documents which changed
                   2212: 	%changes=&Apache::lonnet::dump
1.174     albertel 2213: 	 ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
                   2214:                      $env{'course.'.$env{'request.course.id'}.'.num'});
1.89      www      2215: 	my $firstkey=(keys %changes)[0];
                   2216: 	unless ($firstkey=~/^error\:/) {
1.174     albertel 2217: 	    unless ($env{'form.timerange'}) {
                   2218: 		$env{'form.timerange'}=604800;
1.89      www      2219: 	    }
1.174     albertel 2220: 	    my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
1.89      www      2221: 		.&mt('seconds');
1.174     albertel 2222: 	    if ($env{'form.timerange'}==-1) {
1.89      www      2223: 		$seltext='since start of course';
                   2224: 		$startsel='selected';
1.174     albertel 2225: 		$env{'form.timerange'}=time;
1.89      www      2226: 	    }
1.174     albertel 2227: 	    $starttime=time-$env{'form.timerange'};
                   2228: 	    if ($env{'form.timerange'}==2592000) {
1.89      www      2229: 		$seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2230: 		$monthsel='selected';
1.174     albertel 2231: 	    } elsif ($env{'form.timerange'}==604800) {
1.89      www      2232: 		$seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2233: 		$weeksel='selected';
1.174     albertel 2234: 	    } elsif ($env{'form.timerange'}==86400) {
1.89      www      2235: 		$seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
                   2236: 		$daysel='selected';
                   2237: 	    }
                   2238: 	    $header=&mt('Content changed').' '.$seltext;
                   2239: 	} else {
                   2240: 	    $header=&mt('No content modifications yet.');
                   2241: 	}
                   2242:     }
1.92      www      2243:     %setversions=&Apache::lonnet::dump('resourceversions',
1.174     albertel 2244: 			  $env{'course.'.$env{'request.course.id'}.'.domain'},
                   2245: 			  $env{'course.'.$env{'request.course.id'}.'.num'});
1.89      www      2246:     my %lt=&Apache::lonlocal::texthash
1.229     raeburn  2247: 	      ('st' => 'Version changes since start of '.$type,
1.88      www      2248: 	       'lm' => 'Version changes since last Month',
                   2249: 	       'lw' => 'Version changes since last Week',
                   2250: 	       'sy' => 'Version changes since Yesterday',
1.91      www      2251:                'al' => 'All Resources (possibly large output)',
1.88      www      2252: 	       'sd' => 'Display',
1.84      www      2253: 	       'fi' => 'File',
                   2254: 	       'md' => 'Modification Date',
1.87      www      2255:                'mr' => 'Most recently published Version',
1.229     raeburn  2256: 	       've' => 'Version used in '.$type,
                   2257:                'vu' => 'Set Version to be used in '.$type,
                   2258: 'sv' => 'Set Versions to be used in '.$type.' according to Selections below',
1.91      www      2259: 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
                   2260: 'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
1.84      www      2261: 	       'di' => 'Differences');
1.89      www      2262:     $r->print(<<ENDHEADERS);
1.31      www      2263: <form action="/adm/coursedocs" method="post">
1.91      www      2264: <input type="hidden" name="versions" value="1" />
                   2265: <input type="submit" name="setmostrecent" value="$lt{'sm'}" />
                   2266: <input type="submit" name="setcurrent" value="$lt{'sc'}" /><hr />
1.31      www      2267: <select name="timerange">
1.88      www      2268: <option value='all' $allsel>$lt{'al'}</option>
1.84      www      2269: <option value="-1" $startsel>$lt{'st'}</option>
                   2270: <option value="2592000" $monthsel>$lt{'lm'}</option>
                   2271: <option value="604800" $weeksel>$lt{'lw'}</option>
                   2272: <option value="86400" $daysel>$lt{'sy'}</option>
1.31      www      2273: </select>
1.91      www      2274: <input type="submit" name="display" value="$lt{'sd'}" />
1.89      www      2275: <h3>$header</h3>
1.91      www      2276: <input type="submit" name="setversions" value="$lt{'sv'}" />
1.103     matthew  2277: <table border="0">
1.31      www      2278: ENDHEADERS
1.91      www      2279:     foreach (sort keys %changes) {
1.89      www      2280: 	if ($changes{$_}>$starttime) {
                   2281: 	    my ($root,$extension)=($_=~/^(.*)\.(\w+)$/);
                   2282: 	    my $currentversion=&Apache::lonnet::getversion($_);
1.93      www      2283: 	    if ($currentversion<0) {
                   2284: 		$currentversion=&mt('Could not be determined.');
                   2285: 	    }
1.89      www      2286: 	    my $linkurl=&Apache::lonnet::clutter($_);
                   2287: 	    $r->print(
1.103     matthew  2288: 		      '<tr><td colspan="5"><br /><br /><font size="+1"><b>'.
1.91      www      2289: 		      &Apache::lonnet::gettitle($linkurl).
1.103     matthew  2290:                       '</b></font></td></tr>'.
                   2291:                       '<tr><td>&nbsp;&nbsp;&nbsp;</td>'.
                   2292:                       '<td colspan="4">'.
                   2293:                       '<a href="'.$linkurl.'" target="cat">'.$linkurl.
                   2294: 		      '</a></td></tr>'.
                   2295:                       '<tr><td></td>'.
                   2296:                       '<td title="'.$lt{'md'}.'">'.
1.102     matthew  2297: 		      &Apache::lonlocal::locallocaltime(
                   2298:                            &Apache::lonnet::metadata($root.'.'.$extension,
                   2299:                                                      'lastrevisiondate')
                   2300:                                                         ).
1.103     matthew  2301:                       '</td>'.
1.284     albertel 2302:                       '<td title="'.$lt{'mr'}.'"><span class="LC_nobreak">Most Recent: '.
1.103     matthew  2303:                       '<font size="+1">'.$currentversion.'</font>'.
1.284     albertel 2304:                       '</span></td>'.
                   2305:                       '<td title="'.$lt{'ve'}.'"><span class="LC_nobreak">In '.$type.': '.
1.103     matthew  2306:                       '<font size="+1">');
1.87      www      2307: # Used in course
1.89      www      2308: 	    my $usedversion=$hash{'version_'.$linkurl};
1.93      www      2309: 	    if (($usedversion) && ($usedversion ne 'mostrecent')) {
1.89      www      2310: 		$r->print($usedversion);
                   2311: 	    } else {
                   2312: 		$r->print($currentversion);
                   2313: 	    }
1.284     albertel 2314: 	    $r->print('</font></span></td><td title="'.$lt{'vu'}.'">'.
                   2315:                       '<span class="LC_nobreak">Use: ');
1.87      www      2316: # Set version
1.92      www      2317: 	    $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
1.89      www      2318: 						      'set_version_'.$linkurl,
1.136     albertel 2319: 						      ('select_form_order' =>
                   2320: 						       ['',1..$currentversion,'mostrecent'],
                   2321: 						       '' => '',
1.93      www      2322: 						       'mostrecent' => 'most recent',
1.89      www      2323: 						       map {$_,$_} (1..$currentversion))));
1.284     albertel 2324: 	    $r->print('</span></td></tr><tr><td></td>');
1.89      www      2325: 	    my $lastold=1;
                   2326: 	    for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
                   2327: 		my $url=$root.'.'.$prevvers.'.'.$extension;
                   2328: 		if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
                   2329: 		    $starttime) {
                   2330: 		    $lastold=$prevvers;
                   2331: 		}
                   2332: 	    }
1.103     matthew  2333:             # 
                   2334:             # Code to figure out how many version entries should go in
                   2335:             # each of the four columns
                   2336:             my $entries_per_col = 0;
                   2337:             my $num_entries = ($currentversion-$lastold);
                   2338:             if ($num_entries % 4 == 0) {
                   2339:                 $entries_per_col = $num_entries/4;
                   2340:             } else {
                   2341:                 $entries_per_col = $num_entries/4 + 1;
                   2342:             }
                   2343:             my $entries_count = 0;
                   2344:             $r->print('<td valign="top"><font size="-2">'); 
                   2345:             my $cols_output = 1;
1.32      www      2346:             for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
1.89      www      2347: 		my $url=$root.'.'.$prevvers.'.'.$extension;
1.284     albertel 2348: 		$r->print('<span class="LC_nobreak"><a href="'.&Apache::lonnet::clutter($url).
1.91      www      2349: 			  '">'.&mt('Version').' '.$prevvers.'</a> ('.
1.103     matthew  2350: 			  &Apache::lonlocal::locallocaltime(
                   2351:                                 &Apache::lonnet::metadata($url,
                   2352:                                                           'lastrevisiondate')
                   2353:                                                             ).
1.91      www      2354: 			  ')');
1.89      www      2355: 		if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
1.33      www      2356:                     $r->print(' <a href="/adm/diff?filename='.
1.89      www      2357: 			      &Apache::lonnet::clutter($root.'.'.$extension).
                   2358: 			      '&versionone='.$prevvers.
                   2359: 			      '">'.&mt('Diffs').'</a>');
                   2360: 		}
1.284     albertel 2361: 		$r->print('</span><br />');
1.103     matthew  2362:                 if (++$entries_count % $entries_per_col == 0) {
                   2363:                     $r->print('</font></td>');
                   2364:                     if ($cols_output != 4) {
                   2365:                         $r->print('<td valign="top"><font size="-2">');
                   2366:                         $cols_output++;
                   2367:                     }
                   2368:                 }
1.89      www      2369: 	    }
1.103     matthew  2370:             while($cols_output++ < 4) {
                   2371:                 $r->print('</font></td><td><font>')
                   2372:             }
                   2373: 	    $r->print('</font></td></tr>'."\n");
1.89      www      2374: 	}
                   2375:     }
1.92      www      2376:     $r->print('</table></form>');
1.89      www      2377:     $r->print('<h1>'.&mt('Done').'.</h1>');
                   2378: 
                   2379:     &untiehash();
1.75      www      2380: }
                   2381: 
1.136     albertel 2382: sub mark_hash_old {
                   2383:     my $retie_hash=0;
                   2384:     if ($hashtied) {
                   2385: 	$retie_hash=1;
                   2386: 	&untiehash();
                   2387:     }
                   2388:     &tiehash('write');
                   2389:     $hash{'old'}=1;
                   2390:     &untiehash();
                   2391:     if ($retie_hash) { &tiehash(); }
                   2392: }
                   2393: 
                   2394: sub is_hash_old {
                   2395:     my $untie_hash=0;
                   2396:     if (!$hashtied) {
                   2397: 	$untie_hash=1;
                   2398: 	&tiehash();
                   2399:     }
                   2400:     my $return=$hash{'old'};
                   2401:     if ($untie_hash) { &untiehash(); }
                   2402:     return $return;
                   2403: }
                   2404: 
1.91      www      2405: sub changewarning {
1.177     albertel 2406:     my ($r,$postexec,$message,$url)=@_;
1.136     albertel 2407:     if (!&is_hash_old()) { return; }
1.150     albertel 2408:     my $pathvar='folderpath';
1.228     www      2409:     my $path=&escape($env{'form.folderpath'});
1.177     albertel 2410:     if (!defined($url)) {
                   2411: 	if (defined($env{'form.pagepath'})) {
                   2412: 	    $pathvar='pagepath';
1.228     www      2413: 	    $path=&escape($env{'form.pagepath'});
                   2414: 	    $path.='&amp;pagesymb='.&escape($env{'form.pagesymb'});
1.177     albertel 2415: 	}
                   2416: 	$url='/adm/coursedocs?'.$pathvar.'='.$path;
                   2417:     }
1.230     albertel 2418:     my $course_type = &Apache::loncommon::course_type();
1.177     albertel 2419:     if (!defined($message)) {
                   2420: 	$message='Changes will become active for your current session after [_1], or the next time you log in.';
1.150     albertel 2421:     }
1.185     www      2422:     $r->print("\n\n".
1.286     albertel 2423: '<script type="text/javascript">function reinit(tf) { tf.submit();'.$postexec.' }</script>'."\n". 
1.185     www      2424: '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'.
1.177     albertel 2425: '<input type="hidden" name="orgurl" value="'.$url.
1.283     albertel 2426: '" /><input type="hidden" name="selectrole" value="1" /><h3><span class="LC_warning">'.
1.177     albertel 2427: &mt($message,' <input type="hidden" name="'.
                   2428:     $env{'request.role'}.'" value="1" /><input type="button" value="'.
1.230     albertel 2429:     &mt('re-initializing '.$course_type).'" onClick="reinit(this.form)" />').
1.283     albertel 2430: $help{'Caching'}.'</span></h3></form>'."\n\n");
1.91      www      2431: }
                   2432: 
1.257     www      2433: # =========================================== Breadcrumbs for special functions
                   2434: 
                   2435: sub init_breadcrumbs {
                   2436:     my ($form,$text)=@_;
                   2437:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2438:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs",
                   2439: 					    text=>&Apache::loncommon::course_type()." Documents",
                   2440: 					    faq=>273,
                   2441: 					    bug=>'Instructor Interface',
                   2442:                                             help => 'Docs_Adding_Course_Doc'});
                   2443:     &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
                   2444: 					    text=>$text,
                   2445: 					    faq=>273,
                   2446: 					    bug=>'Instructor Interface'});
                   2447: }
                   2448: 
1.75      www      2449: # ================================================================ Main Handler
                   2450: sub handler {
                   2451:     my $r = shift;
1.82      www      2452:     &Apache::loncommon::content_type($r,'text/html');
1.75      www      2453:     $r->send_http_header;
                   2454:     return OK if $r->header_only;
1.230     albertel 2455:     my $type = &Apache::loncommon::course_type();
1.75      www      2456: 
                   2457: # --------------------------------------------- Initialize help topics for this
1.209     albertel 2458:     foreach ('Adding_Course_Doc','Main_Course_Documents',
                   2459: 	     'Adding_External_Resource','Navigate_Content',
                   2460: 	     'Adding_Folders','Docs_Overview', 'Load_Map',
                   2461: 	     'Supplemental','Score_Upload_Form','Adding_Pages',
                   2462: 	     'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
                   2463: 	     'Check_Resource_Versions','Verify_Content') {
                   2464: 	$help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_);
                   2465:     }
1.75      www      2466:     # Composite help files
                   2467:     $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
                   2468: 		    'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
                   2469:     $help{'Simple Page'} = &Apache::loncommon::help_open_topic(
                   2470: 		    'Docs_About_Simple_Page,Docs_Editing_Templated_Pages');
1.86      albertel 2471:     $help{'Simple Problem'} = &Apache::loncommon::help_open_topic(
                   2472: 		    'Option_Response_Simple');
1.75      www      2473:     $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
                   2474: 		    'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
                   2475:     $help{'My Personal Info'} = &Apache::loncommon::help_open_topic(
                   2476: 		  'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
1.255     raeburn  2477:     $help{'Group Files'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
1.75      www      2478:     $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
1.142     raeburn  2479: 
1.209     albertel 2480: # does this user have privileges to modify docs
                   2481:     my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                   2482:   if ($allowed && $env{'form.verify'}) {
1.257     www      2483:       &init_breadcrumbs('verify','Verify Content');
1.75      www      2484:       &verifycontent($r);
1.209     albertel 2485:   } elsif ($allowed && $env{'form.listsymbs'}) {
1.257     www      2486:       &init_breadcrumbs('listsymbs','List Symbs');
1.208     albertel 2487:       &list_symbs($r);
1.247     www      2488:   } elsif ($allowed && $env{'form.docslog'}) {
1.257     www      2489:       &init_breadcrumbs('docslog','Show Log');
1.247     www      2490:       &docs_change_log($r);
1.209     albertel 2491:   } elsif ($allowed && $env{'form.versions'}) {
1.257     www      2492:       &init_breadcrumbs('versions','Check/Set Resource Versions');
1.75      www      2493:       &checkversions($r);
1.209     albertel 2494:   } elsif ($allowed && $env{'form.dumpcourse'}) {
1.257     www      2495:       &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' DOCS to Construction Space');
1.75      www      2496:       &dumpcourse($r);
1.209     albertel 2497:   } elsif ($allowed && $env{'form.exportcourse'}) {
1.257     www      2498:       &init_breadcrumbs('exportcourse','Export '.&Apache::loncommon::course_type().' to IMS');
1.138     raeburn  2499:       &exportcourse($r);
1.26      www      2500:   } else {
1.7       www      2501: # is this a standard course?
                   2502: 
1.174     albertel 2503:     my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
1.155     raeburn  2504:     my $forcestandard = 0;
1.15      www      2505:     my $forcesupplement;
                   2506:     my $script='';
1.19      www      2507:     my $showdoc=0;
1.142     raeburn  2508:     my $containertag;
                   2509:     my $uploadtag;
1.15      www      2510:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.224     albertel 2511: 					    ['folderpath','pagepath',
1.281     albertel 2512: 					     'pagesymb']);
1.174     albertel 2513:     if ($env{'form.folderpath'}) {
                   2514: 	my (@folderpath)=split('&',$env{'form.folderpath'});
1.228     www      2515: 	$env{'form.foldername'}=&unescape(pop(@folderpath));
1.174     albertel 2516: 	$env{'form.folder'}=pop(@folderpath);
                   2517:     }
                   2518:     if ($env{'form.pagepath'}) {
                   2519:         my (@pagepath)=split('&',$env{'form.pagepath'});
1.228     www      2520:         $env{'form.pagename'}=&unescape(pop(@pagepath));
1.174     albertel 2521:         $env{'form.folder'}=pop(@pagepath);
1.156     albertel 2522:         $containertag = '<input type="hidden" name="pagepath" value="" />'.
                   2523: 	    '<input type="hidden" name="pagesymb" value="" />';
1.282     albertel 2524:         $uploadtag = '<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />'.
                   2525: 	    '<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />';
1.142     raeburn  2526:     }
1.21      www      2527:     if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
1.127     albertel 2528:        $showdoc='/'.$1;
1.21      www      2529:     }
                   2530:     unless ($showdoc) { # got called from remote
1.237     albertel 2531:        if (($env{'form.folder'}=~/^(?:group|default)_/) || 
1.209     albertel 2532:           ($env{'form.folder'} =~ m:^\d+/(pages|sequences)/:)) {
1.155     raeburn  2533:            $forcestandard = 1;
                   2534:        } 
1.174     albertel 2535:        $forcesupplement=($env{'form.folder'}=~/^supplemental_/);
1.7       www      2536: 
1.15      www      2537:        if ($allowed) { 
                   2538:          &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
                   2539:          $script=&Apache::lonratedt::editscript('simple'); 
                   2540:        }
                   2541:     } else { # got called in sequence from course
                   2542:        $allowed=0;
1.3       www      2543:     }
1.4       www      2544: 
                   2545: # get course data
1.174     albertel 2546:     my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
                   2547:     my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.4       www      2548: 
1.225     albertel 2549: # get personal data 
1.174     albertel 2550:     my $uname=$env{'user.name'};
                   2551:     my $udom=$env{'user.domain'};
1.245     albertel 2552:     my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom));
1.14      www      2553: 
1.8       www      2554: # graphics settings
1.4       www      2555: 
1.176     albertel 2556:     $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
1.8       www      2557: 
1.224     albertel 2558:     if ($allowed) {
                   2559: 	$script .= &editing_js($udom,$uname);
1.171     www      2560:     }
1.42      www      2561: # -------------------------------------------------------------------- Body tag
1.224     albertel 2562:     $script = '<script type="text/javascript">'."\n".$script."\n".'</script>';
1.229     raeburn  2563:     $r->print(&Apache::loncommon::start_page("$type Documents", $script,
1.225     albertel 2564: 					     {'force_register' => $showdoc,}).
1.233     albertel 2565: 	      &Apache::loncommon::help_open_menu('','',273,'RAT'));
1.224     albertel 2566:   
1.188     raeburn  2567:   my %allfiles = ();
                   2568:   my %codebase = ();
                   2569:   my ($upload_result,$upload_output);
                   2570:   if ($allowed) {
1.264     albertel 2571:       if (($env{'form.uploaddoc.filename'}) &&
                   2572: 	  ($env{'form.cmd'}=~/^upload_(\w+)/)) {
1.188     raeburn  2573: # Process file upload - phase one - upload and parse primary file.  
1.190     albertel 2574:           $upload_result = &process_file_upload(\$upload_output,$coursenum,
                   2575: 						$coursedom,\%allfiles,
1.194     raeburn  2576: 						\%codebase,$1);
1.188     raeburn  2577:           if ($upload_result eq 'phasetwo') {
                   2578:               $r->print($upload_output);
                   2579:           }
                   2580:       } elsif ($env{'form.phasetwo'}) {
                   2581:           my %newname = ();
                   2582:           my %origname = ();
                   2583:           my %attribs = ();
                   2584:           my $updateflag = 0;
                   2585:           my $residx = $env{'form.newidx'};
1.228     www      2586:           my $primary_url = &unescape($env{'form.primaryurl'});
1.188     raeburn  2587: # Process file upload - phase two - gather secondary files.
                   2588:           for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
                   2589:               if ($env{'form.embedded_item_'.$i.'.filename'}) {
                   2590:                   my $javacodebase;
                   2591:                   $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
1.228     www      2592:                   $origname{$i} = &unescape($env{'form.embedded_orig_'.$i});
1.188     raeburn  2593:                   if (exists($env{'form.embedded_codebase_'.$i})) {
1.228     www      2594:                       $javacodebase =  &unescape($env{'form.embedded_codebase_'.$i});  
1.188     raeburn  2595:                       $origname{$i} =~ s#^\Q$javacodebase\E/##; 
                   2596:                   }
                   2597:                   my @attributes = ();
                   2598:                   if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
                   2599:                       @attributes = split/:/,$env{'form.embedded_attrib_'.$i};
                   2600:                   } else {
                   2601:                       @attributes = ($env{'form.embedded_attrib_'.$i});
                   2602:                   }
                   2603:                   foreach (@attributes) {
1.228     www      2604:                       push(@{$attribs{$i}},&unescape($_));
1.188     raeburn  2605:                   }
                   2606:                   if ($javacodebase) {
                   2607:                       $codebase{$i} = $javacodebase;
                   2608:                       $codebase{$i} =~ s#/$##;
                   2609:                       $updateflag = 1;
                   2610:                   }
                   2611:               }
                   2612:               unless ($newname{$i} eq $origname{$i}) {
                   2613:                   $updateflag = 1;
                   2614:               }
                   2615:           }
                   2616: # Process file upload - phase three - modify primary file
                   2617:           if ($updateflag) {
                   2618:               my ($content,$rtncode);
                   2619:               my $updateflag = 0;
                   2620:               my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
                   2621:               if ($getstatus eq 'ok') {
                   2622:                   foreach my $item (keys %newname) {
                   2623:                       if ($newname{$item} ne $origname{$item}) {
                   2624:                           my $attrib_regexp = '';
                   2625:                           if (@{$attribs{$item}} > 1) {
                   2626:                               $attrib_regexp = join('|',@{$attribs{$item}});
                   2627:                           } else {
                   2628:                               $attrib_regexp = $attribs{$item}[0];
                   2629:                           }
                   2630:                           if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
                   2631:                           } 
                   2632:                           $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi; 
                   2633:                       }
                   2634:                       if (exists($codebase{$item})) {
1.224     albertel 2635:                           $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs
1.188     raeburn  2636:                       }
                   2637:                   }
                   2638: # Save edited file.
                   2639:                   my $saveresult;
                   2640:                   my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
                   2641:                   my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.191     raeburn  2642:                   my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
1.188     raeburn  2643:               } else {
                   2644:                   &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus); 
                   2645:               }
                   2646:           }
                   2647:       }
                   2648:   }
                   2649: 
                   2650:   unless ($showdoc ||  $upload_result eq 'phasetwo') {
1.81      www      2651: # -----------------------------------------------------------------------------
                   2652:        my %lt=&Apache::lonlocal::texthash(
1.229     raeburn  2653:                 'uplm' => 'Upload a new main '.lc($type).' document',
                   2654:                 'upls' => 'Upload a new supplemental '.lc($type).' document',
1.168     www      2655:                 'impp' => 'Import a document',
                   2656:                 'pubd' => 'Published documents',
1.181     www      2657: 		'copm' => 'All documents out of a published map into this folder',
1.81      www      2658:                 'spec' => 'Special documents',
                   2659:                 'upld' => 'Upload Document',
                   2660:                 'srch' => 'Search',
                   2661:                 'impo' => 'Import',
1.232     www      2662: 		'book' => 'Import Bookmarks',
1.81      www      2663:                 'selm' => 'Select Map',
                   2664:                 'load' => 'Load Map',
1.186     www      2665:                 'reco' => 'Recover Deleted Resources',
1.81      www      2666:                 'newf' => 'New Folder',
1.142     raeburn  2667:                 'newp' => 'New Composite Page',
1.81      www      2668:                 'extr' => 'External Resource',
                   2669:                 'syll' => 'Syllabus',
                   2670:                 'navc' => 'Navigate Contents',
                   2671:                 'sipa' => 'Simple Page',
                   2672:                 'sipr' => 'Simple Problem',
1.219     www      2673:                 'drbx' => 'Drop Box',
1.81      www      2674:                 'scuf' => 'Score Upload Form',
                   2675:                 'bull' => 'Bulletin Board',
1.96      sakharuk 2676:                 'mypi' => 'My Personal Info',
1.255     raeburn  2677:                 'grpo' => 'Group Files',
1.101     www      2678: 		'abou' => 'About User',
1.110     raeburn  2679:                 'imsf' => 'Import IMS package',
1.96      sakharuk 2680:                 'file' =>  'File',
                   2681:                 'title' => 'Title',
1.188     raeburn  2682:                 'comment' => 'Comment',
                   2683:                 'parse' => 'If HTML file, upload embedded images/multimedia files'
1.81      www      2684: 					  );
                   2685: # -----------------------------------------------------------------------------
1.42      www      2686:     if ($allowed) {
1.281     albertel 2687: 	&update_paste_buffer($coursenum,$coursedom);
1.74      www      2688:        my $dumpbut=&dumpbutton();
1.138     raeburn  2689:        my $exportbut=&exportbutton();
1.88      www      2690:        my %lt=&Apache::lonlocal::texthash(
                   2691: 					 'vc' => 'Verify Content',
                   2692: 					 'cv' => 'Check/Set Resource Versions',
1.208     albertel 2693: 					 'ls' => 'List Symbs',
1.247     www      2694:                                          'sl' => 'Show Log'
1.88      www      2695: 					  );
1.118     albertel 2696: 
1.174     albertel 2697:        my $folderpath=$env{'form.folderpath'};
1.118     albertel 2698:        if (!$folderpath) {
1.174     albertel 2699: 	   if ($env{'form.folder'} eq '' ||
                   2700: 	       $env{'form.folder'} eq 'supplemental') {
1.118     albertel 2701: 	       $folderpath='default&'.
1.230     albertel 2702: 		   &escape(&mt('Main '.$type.' Documents'));
1.118     albertel 2703: 	   }
                   2704:        }
1.174     albertel 2705:        unless ($env{'form.pagepath'}) {
1.142     raeburn  2706:            $containertag = '<input type="hidden" name="folderpath" value="" />';
1.282     albertel 2707:            $uploadtag = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />';
1.142     raeburn  2708:        }
                   2709: 
1.42      www      2710:        $r->print(<<ENDCOURSEVERIFY);
1.36      www      2711: <form name="renameform" method="post" action="/adm/coursedocs">
1.283     albertel 2712:   <input type="hidden" name="title" />
                   2713:   <input type="hidden" name="cmd" />
                   2714:   <input type="hidden" name="markcopy" />
                   2715:   <input type="hidden" name="copyfolder" />
                   2716:   $containertag
1.36      www      2717: </form>
1.39      www      2718: <form name="simpleedit" method="post" action="/adm/coursedocs">
1.283     albertel 2719:   <input type="hidden" name="importdetail" value="" />
                   2720:   $uploadtag
1.39      www      2721: </form>
1.26      www      2722: <form action="/adm/coursedocs" method="post" name="courseverify">
1.283     albertel 2723:   <div class="LC_docs_course_commands">
                   2724: 
                   2725:       <div>
                   2726:         <input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'}
                   2727:       </div>
                   2728:       <div>
                   2729:         <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'}
                   2730:       </div>
                   2731:         $dumpbut
                   2732:         $exportbut
                   2733:       <div>
                   2734:         <input type="submit" name="listsymbs" value="$lt{'ls'}" />
                   2735:       </div>
                   2736:       <div>
                   2737:         <input type="hidden" name="folder" value="$env{'form.folder'}" />
                   2738:         <input type="submit" name="docslog" value="$lt{'sl'}" />
                   2739:       </div>
                   2740:   </div>
1.25      www      2741: </form>
1.283     albertel 2742: <div style="clear: both; height: 0px;">&nbsp;</div>
1.25      www      2743: ENDCOURSEVERIFY
1.74      www      2744:        $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
1.230     albertel 2745: 		     &mt('Editing the Table of Contents for your '.$type)));
1.25      www      2746:     }
1.17      www      2747: # --------------------------------------------------------- Standard documents
1.285     albertel 2748:     $r->print('<table class="LC_docs_documents">');#border=2 cellspacing=4 cellpadding=4>');
1.7       www      2749:     if (($standard) && ($allowed) && (!$forcesupplement)) {
1.285     albertel 2750: 	$r->print('<tr><td class="LC_docs_document">');
1.116     albertel 2751: #  '<h2>'.&mt('Main Course Documents').
                   2752: #  ($allowed?' '.$help{'Main_Course_Documents'}:'').'</h2>');
1.174     albertel 2753:        my $folder=$env{'form.folder'};
1.117     albertel 2754:        if ($folder eq '' || $folder eq 'supplemental') {
1.112     raeburn  2755:            $folder='default';
1.230     albertel 2756: 	   $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$type.' Documents'));
1.112     raeburn  2757:        }
1.51      www      2758:        my $postexec='';
                   2759:        if ($folder eq 'default') {
1.286     albertel 2760: 	   $r->print('<script type="text/javascript">this.window.name="loncapaclient";</script>');
1.51      www      2761:        } else {
1.117     albertel 2762:            #$postexec='self.close();';
1.51      www      2763:        }
1.40      www      2764:        $hadchanges=0;
1.188     raeburn  2765:        &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output);
1.40      www      2766:        if ($hadchanges) {
1.136     albertel 2767: 	   &mark_hash_old()
1.40      www      2768:        }
1.136     albertel 2769:        &changewarning($r,$postexec);
1.16      www      2770:        my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
                   2771:                      '.sequence';
1.142     raeburn  2772:        my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
                   2773:                      '.page';
1.186     www      2774: 	my $container='sequence';
                   2775: 	if ($env{'form.pagepath'}) {
                   2776: 	    $container='page';
                   2777: 	}
                   2778: 	my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
1.8       www      2779:        $r->print(<<ENDFORM);
1.285     albertel 2780: <table class="LC_docs_adddocs">
                   2781: <tr>
                   2782: <th>$lt{'uplm'}</th>
                   2783: <th>$lt{'impp'}</th>
                   2784: <th>$lt{'spec'}</th>
1.11      www      2785: </tr>
1.285     albertel 2786: <tr>
                   2787: <td>
1.96      sakharuk 2788: $lt{'file'}:<br />
1.182     albertel 2789: <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286     albertel 2790: <input type="file" name="uploaddoc" size="40" />
1.8       www      2791: <br />
1.96      sakharuk 2792: $lt{'title'}:<br />
1.286     albertel 2793: <input type="text" size="50" name="comment" />
1.142     raeburn  2794: $uploadtag
1.286     albertel 2795: <input type="hidden" name="cmd" value="upload_default" />
1.188     raeburn  2796: <br />
1.284     albertel 2797: <span class="LC_nobreak">
1.190     albertel 2798: <label>$lt{'parse'}?
1.188     raeburn  2799: <input type="checkbox" name="parserflag" />
1.190     albertel 2800: </label>
1.284     albertel 2801: </span>
1.188     raeburn  2802: <br />
                   2803: <br />
1.284     albertel 2804: <span class="LC_nobreak">
1.286     albertel 2805: <input type="submit" value="$lt{'upld'}" />
1.60      albertel 2806:  $help{'Uploading_From_Harddrive'}
1.284     albertel 2807: </span>
1.60      albertel 2808: </form>
1.11      www      2809: </td>
1.285     albertel 2810: <td>
1.39      www      2811: <form action="/adm/coursedocs" method="post" name="simpleeditdefault">
1.168     www      2812: $lt{'pubd'}<br />
1.142     raeburn  2813: $uploadtag
1.286     albertel 2814: <input type="button" onClick="javascript:groupsearch()" value="$lt{'srch'}" />
1.232     www      2815: <br />
1.284     albertel 2816: <span class="LC_nobreak">
1.286     albertel 2817: <input type="button" onClick="javascript:groupimport();" value="$lt{'impo'}" />
1.58      albertel 2818: $help{'Importing_LON-CAPA_Resource'}
1.284     albertel 2819: </span>
1.232     www      2820: <br />
1.286     albertel 2821: <input type="button" onClick="javascript:groupopen(0,1,1);" value="$lt{'book'}" />
                   2822: <hr />
1.59      www      2823: <p>
1.181     www      2824: $lt{'copm'}<br />
1.282     albertel 2825: <input type="text" size="40" name="importmap" /><br />
1.286     albertel 2826: <span class="LC_nobreak"><input type="button" 
1.52      www      2827: onClick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')"
1.282     albertel 2828: value="$lt{'selm'}" /> <input type="submit" name="loadmap" value="$lt{'load'}" />
1.284     albertel 2829: $help{'Load_Map'}</span>
1.59      www      2830: </p>
1.52      www      2831: </form>
1.186     www      2832: <hr />
                   2833: <form action="/adm/groupsort" method="post" name="recover">
1.232     www      2834: <input type="button" name="recovermap" onClick="javascript:groupopen('$readfile',1,0)" value="$lt{'reco'}" />
1.186     www      2835: </form>
1.142     raeburn  2836: ENDFORM
1.174     albertel 2837:        unless ($env{'form.pagepath'}) {
1.168     www      2838: 	   $r->print(<<ENDFORM);
                   2839: <hr />
                   2840: <form action="/adm/coursedocs" method="post" name="newext">
                   2841: $uploadtag
1.256     albertel 2842: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2843: <span class="LC_nobreak">
1.168     www      2844: <input name="newext" type="button" onClick="javascript:makenewext('newext');"
                   2845: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284     albertel 2846: </span>
1.168     www      2847: </form>
1.214     www      2848: <br /><form action="/adm/imsimportdocs" method="post" name="ims">
1.168     www      2849: <input type="hidden" name="folder" value="$folder" />
                   2850: <input name="imsimport" type="button" value="$lt{'imsf'}" onClick="javascript:makeims();" />
                   2851: </form>
                   2852: ENDFORM
                   2853:        }
1.285     albertel 2854:        $r->print('</td><td>');
1.174     albertel 2855:        unless ($env{'form.pagepath'}) {
1.282     albertel 2856: 	   my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.142     raeburn  2857:            $r->print(<<ENDFORM);
1.214     www      2858: <br /><form action="/adm/coursedocs" method="post" name="newfolder">
1.282     albertel 2859: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 2860: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2861: <span class="LC_nobreak">
1.16      www      2862: <input name="newfolder" type="button"
                   2863: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81      www      2864: value="$lt{'newf'}" />$help{'Adding_Folders'}
1.284     albertel 2865: </span>
1.11      www      2866: </form>
1.214     www      2867: <br /><form action="/adm/coursedocs" method="post" name="newpage">
1.282     albertel 2868: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 2869: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2870: <span class="LC_nobreak">
1.142     raeburn  2871: <input name="newpage" type="button"
                   2872: onClick="javascript:makenewpage(this.form,'$pageseq');"
                   2873: value="$lt{'newp'}" />$help{'Adding_Pages'}
1.284     albertel 2874: </span>
1.142     raeburn  2875: </form>
1.214     www      2876: <br /><form action="/adm/coursedocs" method="post" name="newsyl">
1.142     raeburn  2877: $uploadtag
1.256     albertel 2878: <input type="hidden" name="importdetail" 
                   2879: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.284     albertel 2880: <span class="LC_nobreak">
1.81      www      2881: <input name="newsyl" type="submit" value="$lt{'syll'}" /> 
1.65      bowersj2 2882:  $help{'Syllabus'}
1.284     albertel 2883: </span>
1.58      albertel 2884: </form>
1.214     www      2885: <br /><form action="/adm/coursedocs" method="post" name="newnav">
1.142     raeburn  2886: $uploadtag
1.256     albertel 2887: <input type="hidden" name="importdetail" 
                   2888: value="Navigate Content=/adm/navmaps" />
1.284     albertel 2889: <span class="LC_nobreak">
1.81      www      2890: <input name="newnav" type="submit" value="$lt{'navc'}" />
1.47      www      2891: $help{'Navigate_Content'}
1.284     albertel 2892: </span>
1.22      www      2893: </form>
1.214     www      2894: <br /><form action="/adm/coursedocs" method="post" name="newsmppg">
1.142     raeburn  2895: $uploadtag
1.256     albertel 2896: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2897: <span class="LC_nobreak">
1.81      www      2898: <input name="newsmppg" type="button" value="$lt{'sipa'}"
1.65      bowersj2 2899: onClick="javascript:makesmppage();" /> $help{'Simple Page'}
1.284     albertel 2900: </span>
1.55      www      2901: </form>
1.214     www      2902: <br /><form action="/adm/coursedocs" method="post" name="newsmpproblem">
1.142     raeburn  2903: $uploadtag
1.256     albertel 2904: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2905: <span class="LC_nobreak">
1.81      www      2906: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
1.65      bowersj2 2907: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284     albertel 2908: </span>
1.62      www      2909: </form>
1.219     www      2910: <br /><form action="/adm/coursedocs" method="post" name="newdropbox">
                   2911: $uploadtag      
1.256     albertel 2912: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2913: <span class="LC_nobreak">          
1.219     www      2914: <input name="newdropbox" type="button" value="$lt{'drbx'}"
                   2915: onClick="javascript:makedropbox();" />
1.284     albertel 2916: </span>         
1.219     www      2917: </form> 
1.214     www      2918: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142     raeburn  2919: $uploadtag
1.256     albertel 2920: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2921: <span class="LC_nobreak">
1.81      www      2922: <input name="newexamupload" type="button" value="$lt{'scuf'}"
1.62      www      2923: onClick="javascript:makeexamupload();" />
1.66      bowersj2 2924: $help{'Score_Upload_Form'}
1.284     albertel 2925: </span>
1.22      www      2926: </form>
1.214     www      2927: <br /><form action="/adm/coursedocs" method="post" name="newbul">
1.142     raeburn  2928: $uploadtag
1.256     albertel 2929: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2930: <span class="LC_nobreak">
1.81      www      2931: <input name="newbulletin" type="button" value="$lt{'bull'}"
1.22      www      2932: onClick="javascript:makebulboard();" />
1.65      bowersj2 2933: $help{'Bulletin Board'}
1.284     albertel 2934: </span>
1.58      albertel 2935: </form>
1.214     www      2936: <br /><form action="/adm/coursedocs" method="post" name="newaboutme">
1.142     raeburn  2937: $uploadtag
1.256     albertel 2938: <input type="hidden" name="importdetail" 
                   2939: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284     albertel 2940: <span class="LC_nobreak">
1.81      www      2941: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65      bowersj2 2942: $help{'My Personal Info'}
1.284     albertel 2943: </span>
1.101     www      2944: </form>
1.214     www      2945: <br /><form action="/adm/coursedocs" method="post" name="newaboutsomeone">
1.142     raeburn  2946: $uploadtag
1.256     albertel 2947: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2948: <span class="LC_nobreak">
1.101     www      2949: <input name="newaboutsomeone" type="button" value="$lt{'abou'}" 
                   2950: onClick="javascript:makeabout();" />
1.284     albertel 2951: </span>
1.182     albertel 2952: </form>
1.255     raeburn  2953: <br /><form action="/adm/coursedocs" method="post" name="newgroupfiles">
                   2954: $uploadtag
1.256     albertel 2955: <input type="hidden" name="importdetail"
                   2956: value="Group Files=/adm/$coursedom/$coursenum/aboutme" />
1.284     albertel 2957: <span class="LC_nobreak">
1.255     raeburn  2958: <input name="newgroupfiles" type="submit" value="$lt{'grpo'}" />
                   2959: $help{'Group Files'}
1.284     albertel 2960: </span>
1.255     raeburn  2961: </form>
1.142     raeburn  2962: ENDFORM
                   2963:        }
1.174     albertel 2964:        if ($env{'form.pagepath'}) {
1.142     raeburn  2965:            $r->print(<<ENDBLOCK);
                   2966: <form action="/adm/coursedocs" method="post" name="newsmpproblem">
                   2967: $uploadtag
1.256     albertel 2968: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2969: <span class="LC_nobreak">
1.142     raeburn  2970: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
                   2971: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284     albertel 2972: </span>
1.142     raeburn  2973: </form>
1.214     www      2974: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142     raeburn  2975: $uploadtag
1.256     albertel 2976: <input type="hidden" name="importdetail" value="" />
1.284     albertel 2977: <span class="LC_nobreak">
1.142     raeburn  2978: <input name="newexamupload" type="button" value="$lt{'scuf'}"
                   2979: onClick="javascript:makeexamupload();" />
                   2980: $help{'Score_Upload_Form'}
1.284     albertel 2981: </span>
1.182     albertel 2982: </form>
1.142     raeburn  2983: ENDBLOCK
                   2984:        }
                   2985:        $r->print('</td></tr>'."\n".
                   2986: '</table>');
1.24      www      2987:        $r->print('</td></tr>');
1.7       www      2988:     }
                   2989: # ----------------------------------------------------- Supplemental documents
                   2990:     if (!$forcestandard) {
1.285     albertel 2991:        $r->print('<tr><td class="LC_docs_document">');
1.116     albertel 2992: # '<h2>'.&mt('Supplemental Course Documents').
                   2993: #  ($allowed?' '.$help{'Supplemental'}:'').'</h2>');
1.174     albertel 2994:        my $folder=$env{'form.folder'};
1.117     albertel 2995:        unless ($folder=~/^supplemental/) {
1.116     albertel 2996: 	   $folder='supplemental';
1.117     albertel 2997:        }
                   2998:        if ($folder =~ /^supplemental$/ &&
1.174     albertel 2999: 	   $env{'form.folderpath'} =~ /^default\&/) {
                   3000: 	   $env{'form.folderpath'}='supplemental&'.
1.230     albertel 3001: 	       &escape(&mt('Supplemental '.$type.' Documents'));
1.116     albertel 3002:        }
1.7       www      3003:        &editor($r,$coursenum,$coursedom,$folder,$allowed);
1.8       www      3004:        if ($allowed) {
1.282     albertel 3005: 	   my $folderseq=
                   3006: 	       '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
                   3007: 	       '.sequence';
1.17      www      3008: 
1.282     albertel 3009: 	   my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
                   3010: 	   $r->print(<<ENDSUPFORM);
1.285     albertel 3011: <table class="LC_docs_adddocs"><tr>
                   3012: <th>$lt{'upls'}</th>
                   3013: <th>$lt{'spec'}</th>
1.17      www      3014: </tr>
1.285     albertel 3015: <tr><td>
1.10      www      3016: <form action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286     albertel 3017: <input type="file" name="uploaddoc" size="40" />
1.196     raeburn  3018: <br />
                   3019: <br />
1.284     albertel 3020: <span class="LC_nobreak">
1.196     raeburn  3021: <label>$lt{'parse'}?
                   3022: <input type="checkbox" name="parserflag" />
                   3023: </label>
1.284     albertel 3024: </span>
1.196     raeburn  3025: <br /><br />
                   3026: $lt{'comment'}:<br />
1.4       www      3027: <textarea cols=50 rows=4 name='comment'>
                   3028: </textarea>
1.115     albertel 3029: <br />
1.282     albertel 3030: <input type="hidden" name="folderpath" value="$path" />
1.286     albertel 3031: <input type="hidden" name="cmd" value="upload_supplemental" />
1.284     albertel 3032: <span class="LC_nobreak">
1.286     albertel 3033: <input type="submit" value="$lt{'upld'}" />
1.58      albertel 3034:  $help{'Uploading_From_Harddrive'}
1.284     albertel 3035: </span>
1.58      albertel 3036: </form>
1.17      www      3037: </td>
1.285     albertel 3038: <td>
1.18      www      3039: <form action="/adm/coursedocs" method="post" name="supnewfolder">
1.282     albertel 3040: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3041: <input type="hidden" name="importdetail" value="" />
1.284     albertel 3042: <span class="LC_nobreak">
1.17      www      3043: <input name="newfolder" type="button"
                   3044: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81      www      3045: value="$lt{'newf'}" /> $help{'Adding_Folders'}
1.284     albertel 3046: </span>
1.17      www      3047: </form>
1.214     www      3048: <br /><form action="/adm/coursedocs" method="post" name="supnewext">
1.282     albertel 3049: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3050: <input type="hidden" name="importdetail" value="" />
1.284     albertel 3051: <span class="LC_nobreak">
1.18      www      3052: <input name="newext" type="button" 
                   3053: onClick="javascript:makenewext('supnewext');"
1.81      www      3054: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284     albertel 3055: </span>
1.17      www      3056: </form>
1.214     www      3057: <br /><form action="/adm/coursedocs" method="post" name="supnewsyl">
1.282     albertel 3058: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3059: <input type="hidden" name="importdetail" 
                   3060: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.284     albertel 3061: <span class="LC_nobreak">
1.81      www      3062: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65      bowersj2 3063: $help{'Syllabus'}
1.284     albertel 3064: </span>
1.58      albertel 3065: </form>
1.214     www      3066: <br /><form action="/adm/coursedocs" method="post" name="subnewaboutme">
1.282     albertel 3067: <input type="hidden" name="folderpath" value="$path" />
1.256     albertel 3068: <input type="hidden" name="importdetail" 
                   3069: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284     albertel 3070: <span class="LC_nobreak">
1.81      www      3071: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65      bowersj2 3072: $help{'My Personal Info'}
1.284     albertel 3073: </span>
1.58      albertel 3074: </form>
1.17      www      3075: </td></tr>
1.24      www      3076: </table></td></tr>
1.8       www      3077: ENDSUPFORM
                   3078:        }
1.7       www      3079:     }
1.286     albertel 3080:     $r->print('</table>');
1.18      www      3081:     if ($allowed) {
1.287   ! albertel 3082: 	$r->print('
        !          3083: <form method="post" name="extimport" action="/adm/coursedocs">
        !          3084:   <input type="hidden" name="title" />
        !          3085:   <input type="hidden" name="url" />
        !          3086:   <input type="hidden" name="useform" />
        !          3087:   <input type="hidden" name="residx" />
        !          3088: </form>');
1.18      www      3089:     }
1.19      www      3090:   } else {
1.188     raeburn  3091:       unless ($upload_result eq 'phasetwo') {
1.19      www      3092: # -------------------------------------------------------- This is showdoc mode
1.188     raeburn  3093:           $r->print("<h1>".&mt('Uploaded Document').' - '.
1.141     albertel 3094: 		&Apache::lonnet::gettitle($r->uri).'</h1><p>'.
1.286     albertel 3095: &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><table>".
                   3096:           &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table>');
1.188     raeburn  3097:       }
1.19      www      3098:   }
1.26      www      3099:  }
1.224     albertel 3100:  $r->print(&Apache::loncommon::end_page());
1.26      www      3101:  return OK;
1.1       www      3102: } 
                   3103: 
1.224     albertel 3104: 
                   3105: sub editing_js {
                   3106:     my ($udom,$uname) = @_;
                   3107:     my $now = time();
                   3108: 
                   3109:     return <<ENDNEWSCRIPT;
                   3110: function makenewfolder(targetform,folderseq) {
                   3111:     var foldername=prompt('Name of New Folder','New Folder');
                   3112:     if (foldername) {
1.236     albertel 3113:        targetform.importdetail.value=escape(foldername)+"="+folderseq;
1.224     albertel 3114:         targetform.submit();
                   3115:     }
                   3116: }
                   3117: 
                   3118: function makenewpage(targetform,folderseq) {
                   3119:     var pagename=prompt('Name of New Page','New Page');
                   3120:     if (pagename) {
1.236     albertel 3121:         targetform.importdetail.value=escape(pagename)+"="+folderseq;
1.224     albertel 3122:         targetform.submit();
                   3123:     }
                   3124: }
                   3125: 
                   3126: function makenewext(targetname) {
                   3127:     this.document.forms.extimport.useform.value=targetname;
1.287   ! albertel 3128:     this.document.forms.extimport.title.value='';
        !          3129:     this.document.forms.extimport.url.value='';
        !          3130:     this.document.forms.extimport.residx.value='';
        !          3131:     window.open('/adm/rat/extpickframe.html');
        !          3132: }
        !          3133: 
        !          3134: function edittext(targetname,residx,title,url) {
        !          3135:     this.document.forms.extimport.useform.value=targetname;
        !          3136:     this.document.forms.extimport.residx.value=residx;
        !          3137:     this.document.forms.extimport.url.value=url;
        !          3138:     this.document.forms.extimport.title.value=title;
1.224     albertel 3139:     window.open('/adm/rat/extpickframe.html');
                   3140: }
                   3141: 
                   3142: function makeexamupload() {
                   3143:    var title=prompt('Listed Title for the Uploaded Score');
                   3144:    if (title) { 
                   3145:     this.document.forms.newexamupload.importdetail.value=
1.236     albertel 3146: 	escape(title)+'=/res/lib/templates/examupload.problem';
1.224     albertel 3147:     this.document.forms.newexamupload.submit();
                   3148:    }
                   3149: }
                   3150: 
                   3151: function makesmppage() {
                   3152:    var title=prompt('Listed Title for the Page');
                   3153:    if (title) { 
                   3154:     this.document.forms.newsmppg.importdetail.value=
1.236     albertel 3155: 	escape(title)+'=/adm/$udom/$uname/$now/smppg';
1.224     albertel 3156:     this.document.forms.newsmppg.submit();
                   3157:    }
                   3158: }
                   3159: 
                   3160: function makesmpproblem() {
                   3161:    var title=prompt('Listed Title for the Problem');
                   3162:    if (title) { 
                   3163:     this.document.forms.newsmpproblem.importdetail.value=
1.236     albertel 3164: 	escape(title)+'=/res/lib/templates/simpleproblem.problem';
1.224     albertel 3165:     this.document.forms.newsmpproblem.submit();
                   3166:    }
                   3167: }
                   3168: 
                   3169: function makedropbox() {
                   3170:    var title=prompt('Listed Title for the Drop Box');
                   3171:    if (title) { 
                   3172:     this.document.forms.newdropbox.importdetail.value=
1.236     albertel 3173:         escape(title)+'=/res/lib/templates/DropBox.problem';
1.224     albertel 3174:     this.document.forms.newdropbox.submit();
                   3175:    }
                   3176: }
                   3177: 
                   3178: function makebulboard() {
                   3179:    var title=prompt('Listed Title for the Bulletin Board');
                   3180:    if (title) {
                   3181:     this.document.forms.newbul.importdetail.value=
1.236     albertel 3182: 	escape(title)+'=/adm/$udom/$uname/$now/bulletinboard';
1.224     albertel 3183:     this.document.forms.newbul.submit();
                   3184:    }
                   3185: }
                   3186: 
                   3187: function makeabout() {
1.236     albertel 3188:    var user=prompt("Enter user:domain for User's 'About Me' Page");
1.224     albertel 3189:    if (user) {
                   3190:        var comp=new Array();
1.236     albertel 3191:        comp=user.split(':');
1.224     albertel 3192:        if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) {
                   3193: 	   if ((comp[0]) && (comp[1])) {
                   3194: 	       this.document.forms.newaboutsomeone.importdetail.value=
1.236     albertel 3195: 		   'About '+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme';
1.224     albertel 3196: 	       this.document.forms.newaboutsomeone.submit();
                   3197: 	   } else {
1.236     albertel 3198:                alert("Not a valid user:domain");
1.224     albertel 3199:            }
                   3200:        } else {
1.236     albertel 3201:            alert("Please enter both user and domain in the format user:domain"); 
1.224     albertel 3202:        }
                   3203:    }
                   3204: }
                   3205: 
                   3206: function makeims() {
                   3207:     var caller = document.forms.ims.folder.value;
                   3208:     var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one";
                   3209:     newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes");
                   3210:     newWindow.location.href = newlocation;
                   3211: }
                   3212: 
                   3213: 
                   3214: function finishpick() {
                   3215:     var title=this.document.forms.extimport.title.value;
                   3216:     var url=this.document.forms.extimport.url.value;
                   3217:     var form=this.document.forms.extimport.useform.value;
1.287   ! albertel 3218:     var residx=this.document.forms.extimport.residx.value;
        !          3219:     eval('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+'='+residx+'";this.document.forms.'+form+'.submit();');
1.224     albertel 3220: }
                   3221: 
                   3222: function changename(folderpath,index,oldtitle,container,pagesymb) {
                   3223:     var title=prompt('New Title',oldtitle);
                   3224:     if (title) {
1.281     albertel 3225: 	this.document.forms.renameform.markcopy.value=-1;
1.224     albertel 3226: 	this.document.forms.renameform.title.value=title;
                   3227: 	this.document.forms.renameform.cmd.value='rename_'+index;
                   3228:         if (container == 'sequence') {
                   3229: 	    this.document.forms.renameform.folderpath.value=folderpath;
                   3230:         }
                   3231:         if (container == 'page') {
                   3232:             this.document.forms.renameform.pagepath.value=folderpath;
                   3233:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3234:         }
                   3235:         this.document.forms.renameform.submit();
                   3236:     }
                   3237: }
                   3238: 
                   3239: function removeres(folderpath,index,oldtitle,container,pagesymb) {
                   3240:     if (confirm('WARNING: Removing a resource makes associated grades and scores inaccessible!\\nRemove "'+oldtitle+'"?')) {
1.281     albertel 3241: 	this.document.forms.renameform.markcopy.value=-1;
1.224     albertel 3242: 	this.document.forms.renameform.cmd.value='del_'+index;
                   3243:         if (container == 'sequence') {
                   3244:             this.document.forms.renameform.folderpath.value=folderpath;
                   3245:         }
                   3246:         if (container == 'page') {
                   3247:             this.document.forms.renameform.pagepath.value=folderpath;
                   3248:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3249:         }
                   3250:         this.document.forms.renameform.submit();
                   3251:     }
                   3252: }
                   3253: 
1.281     albertel 3254: function cutres(folderpath,index,oldtitle,container,pagesymb,folder) {
1.224     albertel 3255:     if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible!\\nGrades remain inaccessible if resource is pasted into another folder.\\nCut "'+oldtitle+'"?')) {
                   3256: 	this.document.forms.renameform.cmd.value='cut_'+index;
                   3257: 	this.document.forms.renameform.markcopy.value=index;
1.281     albertel 3258: 	this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224     albertel 3259:         if (container == 'sequence') {
                   3260:             this.document.forms.renameform.folderpath.value=folderpath;
                   3261:         }
                   3262:         if (container == 'page') {
                   3263:             this.document.forms.renameform.pagepath.value=folderpath;
                   3264:             this.document.forms.renameform.pagesymb.value=pagesymb;
                   3265:         }
                   3266:         this.document.forms.renameform.submit();
                   3267:     }
                   3268: }
                   3269: 
1.281     albertel 3270: function markcopy(folderpath,index,oldtitle,container,pagesymb,folder) {
1.224     albertel 3271:     this.document.forms.renameform.markcopy.value=index;
1.281     albertel 3272:     this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224     albertel 3273:     if (container == 'sequence') {
                   3274: 	this.document.forms.renameform.folderpath.value=folderpath;
                   3275:     }
                   3276:     if (container == 'page') {
                   3277: 	this.document.forms.renameform.pagepath.value=folderpath;
                   3278: 	this.document.forms.renameform.pagesymb.value=pagesymb;
                   3279:     }
                   3280:     this.document.forms.renameform.submit();
                   3281: }
                   3282: 
                   3283: ENDNEWSCRIPT
                   3284: }
1.1       www      3285: 1;
                   3286: __END__

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