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

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

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