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

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

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