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

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

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