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

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

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