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

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

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