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

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

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