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