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

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

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