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

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

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