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

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

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