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

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

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