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