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

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

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