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

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

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