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

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

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