Annotation of loncom/interface/londocs.pm, revision 1.264
1.1 www 1: # The LearningOnline Network
1.2 www 2: # Documents
1.1 www 3: #
1.264 ! albertel 4: # $Id: londocs.pm,v 1.263 2006/12/01 22:17:26 albertel Exp $
1.1 www 5: #
1.3 www 6: # Copyright Michigan State University Board of Trustees
1.1 www 7: #
1.3 www 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
1.1 www 9: #
1.3 www 10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
1.1 www 14: #
1.3 www 15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
1.2 www 29: package Apache::londocs;
1.1 www 30:
31: use strict;
1.28 www 32: use Apache::Constants qw(:common :http);
1.158 raeburn 33: use Apache::imsexport;
1.4 www 34: use Apache::lonnet;
35: use Apache::loncommon;
1.245 albertel 36: use LONCAPA::map();
37: use Apache::lonratedt();
1.15 www 38: use Apache::lonxml;
1.244 albertel 39: use Apache::lonclonecourse;
1.138 raeburn 40: use Apache::lonnavmaps;
1.38 www 41: use HTML::Entities;
1.27 www 42: use GDBM_File;
1.81 www 43: use Apache::lonlocal;
1.143 raeburn 44: use Cwd;
1.264 ! albertel 45: use LONCAPA qw(:DEFAULT :match);
1.7 www 46:
1.8 www 47: my $iconpath;
1.7 www 48:
1.27 www 49: my %hash;
50:
51: my $hashtied;
1.29 www 52: my %alreadyseen=();
1.27 www 53:
1.40 www 54: my $hadchanges;
55:
1.47 www 56: # Available help topics
57:
58: my %help=();
59:
1.245 albertel 60: # Mapread read maps into LONCAPA::map:: global arrays
1.10 www 61: # @order and @resources, determines status
1.7 www 62: # sets @order - pointer to resources in right order
63: # sets @resources - array with the resources with correct idx
64: #
65:
66: sub mapread {
67: my ($coursenum,$coursedom,$map)=@_;
68: return
1.245 albertel 69: &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
70: $map);
1.7 www 71: }
72:
73: sub storemap {
74: my ($coursenum,$coursedom,$map)=@_;
1.104 albertel 75: my ($outtext,$errtext)=
1.245 albertel 76: &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
77: $map,1);
1.104 albertel 78: if ($errtext) { return ($errtext,2); }
79:
80: $hadchanges=1;
81: return ($errtext,0);
1.7 www 82: }
83:
1.74 www 84: # ----------------------------------------- Return hash with valid author names
85:
86: sub authorhosts {
87: my %outhash=();
88: my $home=0;
89: my $other=0;
1.174 albertel 90: foreach (keys %env) {
1.74 www 91: if ($_=~/^user\.role\.(au|ca)\.(.+)$/) {
92: my $role=$1;
93: my $realm=$2;
1.174 albertel 94: my ($start,$end)=split(/\./,$env{$_});
1.74 www 95: if (($start) && ($start>time)) { next; }
96: if (($end) && (time>$end)) { next; }
97: my $ca; my $cd;
98: if ($1 eq 'au') {
1.174 albertel 99: $ca=$env{'user.name'};
100: $cd=$env{'user.domain'};
1.74 www 101: } else {
1.264 ! albertel 102: ($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
1.74 www 103: }
1.107 albertel 104: my $allowed=0;
105: my $myhome=&Apache::lonnet::homeserver($ca,$cd);
106: my @ids=&Apache::lonnet::current_machine_ids();
107: foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } }
108: if ($allowed) {
1.74 www 109: $home++;
110: $outhash{'home_'.$ca.'@'.$cd}=1;
111: } else {
1.107 albertel 112: $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome;
1.74 www 113: $other++;
114: }
115: }
116: }
117: return ($home,$other,%outhash);
118: }
119: # ------------------------------------------------------ Generate "dump" button
120:
121: sub dumpbutton {
122: my ($home,$other,%outhash)=&authorhosts();
1.230 albertel 123: my $type = &Apache::loncommon::course_type();
1.74 www 124: if ($home+$other==0) { return ''; }
125: my $output='</td><td bgcolor="#DDDDCC">';
126: if ($home) {
127: return '</td><td bgcolor="#DDDDCC">'.
1.81 www 128: '<input type="submit" name="dumpcourse" value="'.
1.230 albertel 129: &mt('Dump '.$type.' DOCS to Construction Space').'" />'.
1.130 www 130: &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs');
1.74 www 131: } else {
132: return'</td><td bgcolor="#DDDDCC">'.
1.230 albertel 133: &mt('Dump '.$type.
134: ' DOCS to Construction Space: available on other servers');
1.74 www 135: }
136: }
137:
1.164 albertel 138: sub clean {
139: my ($title)=@_;
140: $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
141: return $title;
142: }
1.74 www 143: # -------------------------------------------------------- Actually dump course
144:
145: sub dumpcourse {
1.224 albertel 146: my ($r) = @_;
1.230 albertel 147: my $type = &Apache::loncommon::course_type();
148: $r->print(&Apache::loncommon::start_page('Dump '.$type.' DOCS to Construction Space').
149: '<form name="dumpdoc" method="post">');
1.257 www 150: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Dump '.$type.' DOCS to Construction Space'));
1.74 www 151: my ($home,$other,%outhash)=&authorhosts();
1.75 www 152: unless ($home) { return ''; }
1.174 albertel 153: my $origcrsid=$env{'request.course.id'};
1.76 www 154: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
1.174 albertel 155: if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
1.76 www 156: # Do the dumping
1.174 albertel 157: unless ($outhash{'home_'.$env{'form.authorspace'}}) { return ''; }
158: my ($ca,$cd)=split(/\@/,$env{'form.authorspace'});
1.87 www 159: $r->print('<h3>'.&mt('Copying Files').'</h3>');
1.174 albertel 160: my $title=$env{'form.authorfolder'};
1.164 albertel 161: $title=&clean($title);
1.79 www 162: my %replacehash=();
1.174 albertel 163: foreach (keys %env) {
1.79 www 164: if ($_=~/^form\.namefor\_(.+)/) {
1.174 albertel 165: $replacehash{$1}=$env{$_};
1.79 www 166: }
167: }
1.174 albertel 168: my $crs='/uploaded/'.$env{'request.course.id'}.'/';
1.79 www 169: $crs=~s/\_/\//g;
170: foreach (keys %replacehash) {
171: my $newfilename=$title.'/'.$replacehash{$_};
1.205 albertel 172: $newfilename=~s/\.(\w+)$//;
173: my $ext=$1;
1.164 albertel 174: $newfilename=&clean($newfilename);
1.205 albertel 175: $newfilename.='.'.$ext;
1.79 www 176: my @dirs=split(/\//,$newfilename);
177: my $path='/home/'.$ca.'/public_html';
178: my $makepath=$path;
179: my $fail=0;
180: for (my $i=0;$i<$#dirs;$i++) {
181: $makepath.='/'.$dirs[$i];
182: unless (-e $makepath) {
183: unless(mkdir($makepath,0777)) { $fail=1; }
184: }
185: }
186: $r->print('<br /><tt>'.$_.'</tt> => <tt>'.$newfilename.'</tt>: ');
187: if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
188: if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
1.244 albertel 189: print $fh &Apache::lonclonecourse::rewritefile(
190: &Apache::lonclonecourse::readfile($env{'request.course.id'},$_),
1.79 www 191: (%replacehash,$crs => '')
192: );
193: } else {
194: print $fh
1.244 albertel 195: &Apache::lonclonecourse::readfile($env{'request.course.id'},$_);
1.79 www 196: }
197: $fh->close();
198: } else {
199: $fail=1;
200: }
201: if ($fail) {
202: $r->print('<font color="red">fail</font>');
203: } else {
204: $r->print('<font color="green">ok</font>');
205: }
206: }
1.76 www 207: } else {
208: # Input form
209: unless ($home==1) {
210: $r->print(
1.81 www 211: '<h3>'.&mt('Select the Construction Space').'</h3><select name="authorspace">');
1.76 www 212: }
213: foreach (sort keys %outhash) {
214: if ($_=~/^home_(.+)$/) {
215: if ($home==1) {
216: $r->print(
217: '<input type="hidden" name="authorspace" value="'.$1.'" />');
218: } else {
1.133 www 219: $r->print('<option value="'.$1.'">'.$1.' - '.
220: &Apache::loncommon::plainname(split(/\@/,$1)).'</option>');
1.76 www 221: }
222: }
223: }
224: unless ($home==1) {
225: $r->print('</select>');
226: }
227: my $title=$origcrsdata{'description'};
1.227 albertel 228: $title=~s/[\/\s]+/\_/gs;
1.164 albertel 229: $title=&clean($title);
1.81 www 230: $r->print('<h3>'.&mt('Folder in Construction Space').'</h3><input type="text" size="50" name="authorfolder" value="'.$title.'" /><br />');
1.76 www 231: &tiehash();
1.81 www 232: $r->print('<h3>'.&mt('Filenames in Construction Space').'</h3><table border="2"><tr><th>'.&mt('Internal Filename').'</th><th>'.&mt('Title').'</th><th>'.&mt('Save as ...').'</th></tr>');
1.244 albertel 233: foreach (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
1.78 www 234: $r->print('<tr><td>'.$_.'</td>');
235: my ($ext)=($_=~/\.(\w+)$/);
236: my $title=$hash{'title_'.$hash{
237: 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}};
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;
1.264 ! albertel 369: if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
1.158 raeburn 370: unless ($ressymb =~ m|adm/wrapper/adm|) {
371: $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
372: }
373: }
1.138 raeburn 374: my $color = $count%2;
375: $display .='<tr bgcolor='.$bgcolors[$color].'><td>'."\n".
376: '<input type="checkbox" name="archive" value="'.$count.'" ';
377: if (($curRes->is_sequence()) || ($curRes->is_page())) {
378: my $checkitem = $count + $boards + $startcount;
379: $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"';
380: }
381: $display .= ' />'."\n";
382: for (my $i=0; $i<$depth; $i++) {
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;
1.264 ! albertel 616: if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
1.158 raeburn 617: unless ($ressymb =~ m|adm/wrapper/adm|) {
618: $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
619: }
620: $mode = 'board';
621: }
622: my %extras = (
623: caller => 'imsexport',
1.159 raeburn 624: tempexport => $tempexport.'/resources',
1.158 raeburn 625: count => $count
626: );
627: my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras);
628: }
1.157 raeburn 629: $imsresources .= ' </resource>'."\n";
1.143 raeburn 630: }
631: }
1.157 raeburn 632: $pkgdepth = $depth;
1.143 raeburn 633: }
634: }
635: }
1.157 raeburn 636: while ($pkgdepth > 0) {
1.143 raeburn 637: print $ims_manifest " </item>\n";
638: $pkgdepth --;
639: }
640: my $resource_text = qq|
641: </organization>
642: </organizations>
643: <resources>
644: $imsresources
645: </resources>
646: </manifest>
647: |;
648: print $ims_manifest $resource_text;
649: }
650:
651: sub get_dependencies {
652: my ($exportitems,$parent,$depth,$dependencies) = @_;
653: if ($depth > 1) {
1.157 raeburn 654: if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) {
1.143 raeburn 655: push @$dependencies, $$parent{$depth};
656: if ($depth > 2) {
657: &get_dependencies($exportitems,$parent,$depth-1,$dependencies);
658: }
659: }
660: }
661: }
662:
663: sub process_content {
664: my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport) = @_;
665: my $content_type;
666: my $message;
1.158 raeburn 667: my @uploads = ();
1.157 raeburn 668: if ($curRes->is_sequence()) {
669: $content_type = 'sequence';
670: } elsif ($curRes->is_page()) {
671: $content_type = 'page'; # need to handle individual items in pages.
1.143 raeburn 672: } elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) {
673: $content_type = 'syllabus';
1.158 raeburn 674: my $contents = &Apache::imsexport::templatedpage($content_type);
675: if ($contents) {
676: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
677: }
1.157 raeburn 678: } elsif ($symb =~ m-\.sequence___\d+___ext-) {
1.143 raeburn 679: $content_type = 'external';
1.158 raeburn 680: my $title = $curRes->title;
681: my $contents = &Apache::imsexport::external($symb,$title);
682: if ($contents) {
683: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
684: }
1.143 raeburn 685: } elsif ($symb =~ m-adm/navmaps$-) {
686: $content_type = 'navmap';
1.158 raeburn 687: } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) {
1.143 raeburn 688: $content_type = 'simplepage';
1.158 raeburn 689: my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads);
690: if ($contents) {
691: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
692: }
693: } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) {
1.143 raeburn 694: $content_type = 'simpleproblem';
1.158 raeburn 695: my $contents = &Apache::imsexport::simpleproblem($symb);
696: if ($contents) {
697: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
698: }
1.188 raeburn 699: } elsif ($symb =~ m-lib/templates/examupload\.problem$-) {
1.158 raeburn 700: $content_type = 'examupload';
1.264 ! albertel 701: } elsif ($symb =~ m-adm/($match_domain)/($match_username)/(\d+)/bulletinboard$-) {
1.143 raeburn 702: $content_type = 'bulletinboard';
1.158 raeburn 703: my $contents = &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2);
704: if ($contents) {
705: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
706: }
707: } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) {
1.143 raeburn 708: $content_type = 'aboutme';
1.158 raeburn 709: my $contents = &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2);
710: if ($contents) {
711: $$content_file = &store_template($contents,$tempexport,$count,$content_type);
712: }
1.157 raeburn 713: } elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) {
714: $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
1.162 raeburn 715: } elsif ($symb =~ m-\.(sequence|page)___\d+___([^/]+)/([^/]+)-) {
1.143 raeburn 716: my $canedit = 0;
1.174 albertel 717: if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'}) {
1.143 raeburn 718: $canedit= 1;
719: }
1.200 raeburn 720: # only include problem code where current user is author
1.143 raeburn 721: if ($canedit) {
1.157 raeburn 722: $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource');
1.143 raeburn 723: } else {
1.157 raeburn 724: $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit');
1.143 raeburn 725: }
1.162 raeburn 726: } elsif ($symb =~ m-uploaded/$cdom/$cnum-) {
727: $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
1.143 raeburn 728: }
1.158 raeburn 729: if (@uploads > 0) {
730: foreach my $item (@uploads) {
731: my $uploadmsg = '';
1.159 raeburn 732: &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'templateupload');
1.158 raeburn 733: if ($uploadmsg) {
734: $$copyresult .= $uploadmsg."\n";
735: }
736: }
737: }
1.157 raeburn 738: if ($message) {
739: $$copyresult .= $message."\n";
740: }
1.143 raeburn 741: }
742:
743: sub replicate_content {
1.157 raeburn 744: my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_;
1.159 raeburn 745: my ($map,$ind,$url);
746: if ($caller eq 'templateupload') {
747: $url = $symb;
748: $url =~ s#//#/#g;
749: } else {
750: ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
751: }
1.143 raeburn 752: my $content;
753: my $filename;
754: my $repstatus;
1.157 raeburn 755: my $content_name;
756: if ($url =~ m-/([^/]+)$-) {
1.143 raeburn 757: $filename = $1;
758: if (!-e $tempexport.'/resources') {
759: mkdir($tempexport.'/resources',0700);
760: }
1.157 raeburn 761: if (!-e $tempexport.'/resources/'.$count) {
1.143 raeburn 762: mkdir($tempexport.'/resources/'.$count,0700);
763: }
1.157 raeburn 764: my $destination = $tempexport.'/resources/'.$count.'/'.$filename;
1.143 raeburn 765: my $copiedfile;
766: if ($copiedfile = Apache::File->new('>'.$destination)) {
767: my $content;
1.157 raeburn 768: if ($caller eq 'resource') {
1.197 raeburn 769: my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
770: my $filepath = &Apache::lonnet::filelocation($respath,$url);
771: $content = &Apache::lonnet::getfile($filepath);
1.143 raeburn 772: if ($content eq -1) {
773: $$message = 'Could not copy file '.$filename;
774: } else {
1.197 raeburn 775: &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource');
1.143 raeburn 776: $repstatus = 'ok';
777: }
1.162 raeburn 778: } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') {
1.143 raeburn 779: my $rtncode;
1.157 raeburn 780: $repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode);
781: if ($repstatus eq 'ok') {
782: if ($url =~ /\.html?$/i) {
1.197 raeburn 783: &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
1.157 raeburn 784: }
785: } else {
1.197 raeburn 786: $$message = 'Could not render '.$url.' server message - '.$rtncode."<br />\n";
1.143 raeburn 787: }
1.162 raeburn 788: } elsif ($caller eq 'noedit') {
789: # Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this.
790: $repstatus = 'ok';
791: $content = 'Not the owner of this resource';
1.143 raeburn 792: }
793: if ($repstatus eq 'ok') {
794: print $copiedfile $content;
795: }
796: close($copiedfile);
797: } else {
1.197 raeburn 798: $$message = 'Could not open destination file for '.$filename."<br />\n";
1.143 raeburn 799: }
800: } else {
1.197 raeburn 801: $$message = 'Could not determine name of file for '.$symb."<br />\n";
1.143 raeburn 802: }
1.157 raeburn 803: if ($repstatus eq 'ok') {
1.198 raeburn 804: $content_name = 'resources/'.$count.'/'.$filename;
1.157 raeburn 805: }
806: return $content_name;
807: }
808:
809: sub extract_media {
1.197 raeburn 810: my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_;
1.198 raeburn 811: my ($dirpath,$container);
1.197 raeburn 812: my %allfiles = ();
813: my %codebase = ();
1.198 raeburn 814: if ($url =~ m-(.*/)([^/]+)$-) {
815: $dirpath = $1;
816: $container = $2;
817: } else {
818: $dirpath = $url;
819: $container = '';
820: }
1.197 raeburn 821: &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content);
822: foreach my $embed_file (keys(%allfiles)) {
823: my $filename;
824: if ($embed_file =~ m#([^/]+)$#) {
825: $filename = $1;
826: } else {
827: $filename = $embed_file;
828: }
829: my $newname = 'res/'.$filename;
830: my ($rtncode,$embed_content,$repstatus);
831: my $embed_url;
832: if ($embed_file =~ m-^/-) {
833: $embed_url = $embed_file; # points to absolute path
834: } else {
835: if ($embed_file =~ m-https?://-) {
836: next; # points to url
837: } else {
1.198 raeburn 838: $embed_url = $dirpath.$embed_file; # points to relative path
1.197 raeburn 839: }
840: }
841: if ($caller eq 'resource') {
842: my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
843: my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url);
844: $embed_content = &Apache::lonnet::getfile($embed_path);
845: unless ($embed_content eq -1) {
846: $repstatus = 'ok';
847: }
848: } elsif ($caller eq 'uploaded') {
849:
850: $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode);
851: }
852: if ($repstatus eq 'ok') {
853: my $destination = $tempexport.'/resources/'.$count.'/res';
854: if (!-e "$destination") {
855: mkdir($destination,0755);
856: }
857: $destination .= '/'.$filename;
858: my $copiedfile;
859: if ($copiedfile = Apache::File->new('>'.$destination)) {
860: print $copiedfile $embed_content;
1.198 raeburn 861: push @{$href}, 'resources/'.$count.'/res/'.$filename;
1.197 raeburn 862: my $attrib_regexp = '';
863: if (@{$allfiles{$embed_file}} > 1) {
864: $attrib_regexp = join('|',@{$allfiles{$embed_file}});
865: } else {
866: $attrib_regexp = $allfiles{$embed_file}[0];
867: }
868: $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi;
1.198 raeburn 869: if ($caller eq 'resource' && $container =~ /\.(problem|library)$/) {
1.197 raeburn 870: $$content =~ s#\Q$embed_file\E#$newname#gi;
871: }
872: }
873: } else {
874: $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode."<br />\n";
875: }
876: }
1.157 raeburn 877: return;
1.143 raeburn 878: }
1.74 www 879:
1.158 raeburn 880: sub store_template {
881: my ($contents,$tempexport,$count,$content_type) = @_;
882: if ($contents) {
1.159 raeburn 883: if ($tempexport) {
884: if (!-e $tempexport.'/resources') {
885: mkdir($tempexport.'/resources',0700);
886: }
887: if (!-e $tempexport.'/resources/'.$count) {
888: mkdir($tempexport.'/resources/'.$count,0700);
889: }
890: my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml';
891: my $storetemplate;
892: if ($storetemplate = Apache::File->new('>'.$destination)) {
893: print $storetemplate $contents;
894: close($storetemplate);
895: }
896: if ($content_type eq 'external') {
1.198 raeburn 897: return 'resources/'.$count.'/'.$content_type.'.html';
1.159 raeburn 898: } else {
1.198 raeburn 899: return 'resources/'.$count.'/'.$content_type.'.xml';
1.159 raeburn 900: }
1.158 raeburn 901: }
902: }
903: }
904:
1.73 bowersj2 905: # Imports the given (name, url) resources into the course
906: # coursenum, coursedom, and folder must precede the list
907: sub group_import {
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;
1.264 ! albertel 1312: $storefn=~s{^/\w+/$match_domain/$match_username/}{};
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.264 ! albertel 1635: if ($title=~ /^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/ ) {
1.109 albertel 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';
1.264 ! albertel 1786: $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
1.135 albertel 1787: $url='/adm/coursedocs?';
1788: $folderarg=$1;
1789: $isfolder=1;
1.142 raeburn 1790: } elsif ($extension eq 'page') {
1791: $icon=$iconpath.'/page.gif';
1.264 ! albertel 1792: $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
1.142 raeburn 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) {
1.264 ! albertel 2493: if (($env{'form.uploaddoc.filename'}) &&
! 2494: ($env{'form.cmd'}=~/^upload_(\w+)/)) {
1.188 raeburn 2495: # Process file upload - phase one - upload and parse primary file.
1.190 albertel 2496: $upload_result = &process_file_upload(\$upload_output,$coursenum,
2497: $coursedom,\%allfiles,
1.194 raeburn 2498: \%codebase,$1);
1.188 raeburn 2499: if ($upload_result eq 'phasetwo') {
2500: $r->print($upload_output);
2501: }
2502: } elsif ($env{'form.phasetwo'}) {
2503: my %newname = ();
2504: my %origname = ();
2505: my %attribs = ();
2506: my $updateflag = 0;
2507: my $residx = $env{'form.newidx'};
1.228 www 2508: my $primary_url = &unescape($env{'form.primaryurl'});
1.188 raeburn 2509: # Process file upload - phase two - gather secondary files.
2510: for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
2511: if ($env{'form.embedded_item_'.$i.'.filename'}) {
2512: my $javacodebase;
2513: $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
1.228 www 2514: $origname{$i} = &unescape($env{'form.embedded_orig_'.$i});
1.188 raeburn 2515: if (exists($env{'form.embedded_codebase_'.$i})) {
1.228 www 2516: $javacodebase = &unescape($env{'form.embedded_codebase_'.$i});
1.188 raeburn 2517: $origname{$i} =~ s#^\Q$javacodebase\E/##;
2518: }
2519: my @attributes = ();
2520: if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
2521: @attributes = split/:/,$env{'form.embedded_attrib_'.$i};
2522: } else {
2523: @attributes = ($env{'form.embedded_attrib_'.$i});
2524: }
2525: foreach (@attributes) {
1.228 www 2526: push(@{$attribs{$i}},&unescape($_));
1.188 raeburn 2527: }
2528: if ($javacodebase) {
2529: $codebase{$i} = $javacodebase;
2530: $codebase{$i} =~ s#/$##;
2531: $updateflag = 1;
2532: }
2533: }
2534: unless ($newname{$i} eq $origname{$i}) {
2535: $updateflag = 1;
2536: }
2537: }
2538: # Process file upload - phase three - modify primary file
2539: if ($updateflag) {
2540: my ($content,$rtncode);
2541: my $updateflag = 0;
2542: my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
2543: if ($getstatus eq 'ok') {
2544: foreach my $item (keys %newname) {
2545: if ($newname{$item} ne $origname{$item}) {
2546: my $attrib_regexp = '';
2547: if (@{$attribs{$item}} > 1) {
2548: $attrib_regexp = join('|',@{$attribs{$item}});
2549: } else {
2550: $attrib_regexp = $attribs{$item}[0];
2551: }
2552: if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
2553: }
2554: $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi;
2555: }
2556: if (exists($codebase{$item})) {
1.224 albertel 2557: $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs
1.188 raeburn 2558: }
2559: }
2560: # Save edited file.
2561: my $saveresult;
2562: my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
2563: my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.191 raeburn 2564: my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
1.188 raeburn 2565: } else {
2566: &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus);
2567: }
2568: }
2569: }
2570: }
2571:
2572: unless ($showdoc || $upload_result eq 'phasetwo') {
1.81 www 2573: # -----------------------------------------------------------------------------
2574: my %lt=&Apache::lonlocal::texthash(
1.229 raeburn 2575: 'uplm' => 'Upload a new main '.lc($type).' document',
2576: 'upls' => 'Upload a new supplemental '.lc($type).' document',
1.168 www 2577: 'impp' => 'Import a document',
2578: 'pubd' => 'Published documents',
1.181 www 2579: 'copm' => 'All documents out of a published map into this folder',
1.81 www 2580: 'spec' => 'Special documents',
2581: 'upld' => 'Upload Document',
2582: 'srch' => 'Search',
2583: 'impo' => 'Import',
1.232 www 2584: 'book' => 'Import Bookmarks',
1.81 www 2585: 'selm' => 'Select Map',
2586: 'load' => 'Load Map',
1.186 www 2587: 'reco' => 'Recover Deleted Resources',
1.81 www 2588: 'newf' => 'New Folder',
1.142 raeburn 2589: 'newp' => 'New Composite Page',
1.81 www 2590: 'extr' => 'External Resource',
2591: 'syll' => 'Syllabus',
2592: 'navc' => 'Navigate Contents',
2593: 'sipa' => 'Simple Page',
2594: 'sipr' => 'Simple Problem',
1.219 www 2595: 'drbx' => 'Drop Box',
1.81 www 2596: 'scuf' => 'Score Upload Form',
2597: 'bull' => 'Bulletin Board',
1.96 sakharuk 2598: 'mypi' => 'My Personal Info',
1.255 raeburn 2599: 'grpo' => 'Group Files',
1.101 www 2600: 'abou' => 'About User',
1.110 raeburn 2601: 'imsf' => 'Import IMS package',
1.96 sakharuk 2602: 'file' => 'File',
2603: 'title' => 'Title',
1.188 raeburn 2604: 'comment' => 'Comment',
2605: 'parse' => 'If HTML file, upload embedded images/multimedia files'
1.81 www 2606: );
2607: # -----------------------------------------------------------------------------
1.42 www 2608: if ($allowed) {
1.74 www 2609: my $dumpbut=&dumpbutton();
1.138 raeburn 2610: my $exportbut=&exportbutton();
1.88 www 2611: my %lt=&Apache::lonlocal::texthash(
2612: 'vc' => 'Verify Content',
2613: 'cv' => 'Check/Set Resource Versions',
1.208 albertel 2614: 'ls' => 'List Symbs',
1.247 www 2615: 'sl' => 'Show Log'
1.88 www 2616: );
1.118 albertel 2617:
1.174 albertel 2618: my $folderpath=$env{'form.folderpath'};
1.118 albertel 2619: if (!$folderpath) {
1.174 albertel 2620: if ($env{'form.folder'} eq '' ||
2621: $env{'form.folder'} eq 'supplemental') {
1.118 albertel 2622: $folderpath='default&'.
1.230 albertel 2623: &escape(&mt('Main '.$type.' Documents'));
1.118 albertel 2624: }
2625: }
1.174 albertel 2626: unless ($env{'form.pagepath'}) {
1.142 raeburn 2627: $containertag = '<input type="hidden" name="folderpath" value="" />';
2628: $uploadtag = '<input type="hidden" name="folderpath" value="'.$folderpath.'" />';
2629: }
2630:
1.42 www 2631: $r->print(<<ENDCOURSEVERIFY);
1.36 www 2632: <form name="renameform" method="post" action="/adm/coursedocs">
2633: <input type="hidden" name="title" />
2634: <input type="hidden" name="cmd" />
1.168 www 2635: <input type="hidden" name="markcopy" />
1.142 raeburn 2636: $containertag
1.36 www 2637: </form>
1.39 www 2638: <form name="simpleedit" method="post" action="/adm/coursedocs">
1.256 albertel 2639: <input type="hidden" name="importdetail" value="" />
1.142 raeburn 2640: $uploadtag
1.39 www 2641: </form>
1.26 www 2642: <form action="/adm/coursedocs" method="post" name="courseverify">
1.74 www 2643: <table bgcolor="#AAAAAA" width="100%" cellspacing="4" cellpadding="4">
2644: <tr><td bgcolor="#DDDDCC">
1.130 www 2645: <input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'}
1.74 www 2646: </td><td bgcolor="#DDDDCC">
1.130 www 2647: <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'}
1.74 www 2648: $dumpbut
1.138 raeburn 2649: $exportbut
1.218 albertel 2650: </td><td bgcolor="#DDDDCC">
1.208 albertel 2651: <input type="submit" name="listsymbs" value="$lt{'ls'}" />
1.247 www 2652: </td><td bgcolor="#DDDDCC">
1.260 www 2653: <input type="hidden" name="folder" value="$env{'form.folder'}" />
1.247 www 2654: <input type="submit" name="docslog" value="$lt{'sl'}" />
1.218 albertel 2655: </td></tr></table>
1.25 www 2656: </form>
2657: ENDCOURSEVERIFY
1.74 www 2658: $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
1.230 albertel 2659: &mt('Editing the Table of Contents for your '.$type)));
1.25 www 2660: }
1.17 www 2661: # --------------------------------------------------------- Standard documents
1.43 www 2662: $r->print('<table border=2 cellspacing=4 cellpadding=4>');
1.7 www 2663: if (($standard) && ($allowed) && (!$forcesupplement)) {
1.116 albertel 2664: $r->print('<tr><td bgcolor="#BBBBBB">');
2665: # '<h2>'.&mt('Main Course Documents').
2666: # ($allowed?' '.$help{'Main_Course_Documents'}:'').'</h2>');
1.174 albertel 2667: my $folder=$env{'form.folder'};
1.117 albertel 2668: if ($folder eq '' || $folder eq 'supplemental') {
1.112 raeburn 2669: $folder='default';
1.230 albertel 2670: $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$type.' Documents'));
1.112 raeburn 2671: }
1.51 www 2672: my $postexec='';
2673: if ($folder eq 'default') {
2674: $r->print('<script>this.window.name="loncapaclient";</script>');
2675: } else {
1.117 albertel 2676: #$postexec='self.close();';
1.51 www 2677: }
1.40 www 2678: $hadchanges=0;
1.188 raeburn 2679: &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output);
1.40 www 2680: if ($hadchanges) {
1.136 albertel 2681: &mark_hash_old()
1.40 www 2682: }
1.136 albertel 2683: &changewarning($r,$postexec);
1.16 www 2684: my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
2685: '.sequence';
1.142 raeburn 2686: my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
2687: '.page';
1.186 www 2688: my $container='sequence';
2689: if ($env{'form.pagepath'}) {
2690: $container='page';
2691: }
2692: my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
1.8 www 2693: $r->print(<<ENDFORM);
1.43 www 2694: <table cellspacing=4 cellpadding=4><tr>
1.81 www 2695: <th bgcolor="#DDDDDD">$lt{'uplm'}</th>
2696: <th bgcolor="#DDDDDD">$lt{'impp'}</th>
2697: <th bgcolor="#DDDDDD">$lt{'spec'}</th>
1.11 www 2698: </tr>
1.16 www 2699: <tr><td bgcolor="#DDDDDD">
1.96 sakharuk 2700: $lt{'file'}:<br />
1.182 albertel 2701: <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.59 www 2702: <input type="file" name="uploaddoc" size="40">
1.8 www 2703: <br />
1.96 sakharuk 2704: $lt{'title'}:<br />
1.11 www 2705: <input type="text" size="50" name="comment">
1.142 raeburn 2706: $uploadtag
1.10 www 2707: <input type="hidden" name="cmd" value="upload_default">
1.188 raeburn 2708: <br />
2709: <nobr>
1.190 albertel 2710: <label>$lt{'parse'}?
1.188 raeburn 2711: <input type="checkbox" name="parserflag" />
1.190 albertel 2712: </label>
1.188 raeburn 2713: </nobr>
2714: <br />
2715: <br />
1.129 albertel 2716: <nobr>
1.81 www 2717: <input type="submit" value="$lt{'upld'}">
1.60 albertel 2718: $help{'Uploading_From_Harddrive'}
1.58 albertel 2719: </nobr>
1.60 albertel 2720: </form>
1.11 www 2721: </td>
1.16 www 2722: <td bgcolor="#DDDDDD">
1.39 www 2723: <form action="/adm/coursedocs" method="post" name="simpleeditdefault">
1.168 www 2724: $lt{'pubd'}<br />
1.142 raeburn 2725: $uploadtag
1.232 www 2726: <input type=button onClick="javascript:groupsearch()" value="$lt{'srch'}" />
2727: <br />
1.58 albertel 2728: <nobr>
1.232 www 2729: <input type=button onClick="javascript:groupimport();" value="$lt{'impo'}" />
1.58 albertel 2730: $help{'Importing_LON-CAPA_Resource'}
2731: </nobr>
1.232 www 2732: <br />
2733: <input type=button onClick="javascript:groupopen(0,1,1);" value="$lt{'book'}" />
1.59 www 2734: <p>
2735: <hr />
1.181 www 2736: $lt{'copm'}<br />
2737: <input type="text" size="40" name="importmap"><br />
1.68 bowersj2 2738: <nobr><input type=button
1.52 www 2739: onClick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')"
1.81 www 2740: value="$lt{'selm'}"> <input type="submit" name="loadmap" value="$lt{'load'}">
1.68 bowersj2 2741: $help{'Load_Map'}</nobr>
1.59 www 2742: </p>
1.52 www 2743: </form>
1.186 www 2744: <hr />
2745: <form action="/adm/groupsort" method="post" name="recover">
1.232 www 2746: <input type="button" name="recovermap" onClick="javascript:groupopen('$readfile',1,0)" value="$lt{'reco'}" />
1.186 www 2747: </form>
1.142 raeburn 2748: ENDFORM
1.174 albertel 2749: unless ($env{'form.pagepath'}) {
1.168 www 2750: $r->print(<<ENDFORM);
2751: <hr />
2752: <form action="/adm/coursedocs" method="post" name="newext">
2753: $uploadtag
1.256 albertel 2754: <input type="hidden" name="importdetail" value="" />
1.168 www 2755: <nobr>
2756: <input name="newext" type="button" onClick="javascript:makenewext('newext');"
2757: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
2758: </nobr>
2759: </form>
1.214 www 2760: <br /><form action="/adm/imsimportdocs" method="post" name="ims">
1.168 www 2761: <input type="hidden" name="folder" value="$folder" />
2762: <input name="imsimport" type="button" value="$lt{'imsf'}" onClick="javascript:makeims();" />
2763: </nobr>
2764: </form>
2765: ENDFORM
2766: }
2767: $r->print('</td><td bgcolor="#DDDDDD">');
1.174 albertel 2768: unless ($env{'form.pagepath'}) {
1.142 raeburn 2769: $r->print(<<ENDFORM);
1.214 www 2770: <br /><form action="/adm/coursedocs" method="post" name="newfolder">
1.174 albertel 2771: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2772: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2773: <nobr>
1.16 www 2774: <input name="newfolder" type="button"
2775: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81 www 2776: value="$lt{'newf'}" />$help{'Adding_Folders'}
1.58 albertel 2777: </nobr>
1.11 www 2778: </form>
1.214 www 2779: <br /><form action="/adm/coursedocs" method="post" name="newpage">
1.174 albertel 2780: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2781: <input type="hidden" name="importdetail" value="" />
1.142 raeburn 2782: <nobr>
2783: <input name="newpage" type="button"
2784: onClick="javascript:makenewpage(this.form,'$pageseq');"
2785: value="$lt{'newp'}" />$help{'Adding_Pages'}
2786: </nobr>
2787: </form>
1.214 www 2788: <br /><form action="/adm/coursedocs" method="post" name="newsyl">
1.142 raeburn 2789: $uploadtag
1.256 albertel 2790: <input type="hidden" name="importdetail"
2791: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.58 albertel 2792: <nobr>
1.81 www 2793: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65 bowersj2 2794: $help{'Syllabus'}
1.58 albertel 2795: </nobr>
2796: </form>
1.214 www 2797: <br /><form action="/adm/coursedocs" method="post" name="newnav">
1.142 raeburn 2798: $uploadtag
1.256 albertel 2799: <input type="hidden" name="importdetail"
2800: value="Navigate Content=/adm/navmaps" />
1.58 albertel 2801: <nobr>
1.81 www 2802: <input name="newnav" type="submit" value="$lt{'navc'}" />
1.47 www 2803: $help{'Navigate_Content'}
1.58 albertel 2804: </nobr>
1.22 www 2805: </form>
1.214 www 2806: <br /><form action="/adm/coursedocs" method="post" name="newsmppg">
1.142 raeburn 2807: $uploadtag
1.256 albertel 2808: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2809: <nobr>
1.81 www 2810: <input name="newsmppg" type="button" value="$lt{'sipa'}"
1.65 bowersj2 2811: onClick="javascript:makesmppage();" /> $help{'Simple Page'}
1.58 albertel 2812: </nobr>
1.55 www 2813: </form>
1.214 www 2814: <br /><form action="/adm/coursedocs" method="post" name="newsmpproblem">
1.142 raeburn 2815: $uploadtag
1.256 albertel 2816: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2817: <nobr>
1.81 www 2818: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
1.65 bowersj2 2819: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.62 www 2820: </nobr>
2821: </form>
1.219 www 2822: <br /><form action="/adm/coursedocs" method="post" name="newdropbox">
2823: $uploadtag
1.256 albertel 2824: <input type="hidden" name="importdetail" value="" />
1.219 www 2825: <nobr>
2826: <input name="newdropbox" type="button" value="$lt{'drbx'}"
2827: onClick="javascript:makedropbox();" />
2828: </nobr>
2829: </form>
1.214 www 2830: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142 raeburn 2831: $uploadtag
1.256 albertel 2832: <input type="hidden" name="importdetail" value="" />
1.62 www 2833: <nobr>
1.81 www 2834: <input name="newexamupload" type="button" value="$lt{'scuf'}"
1.62 www 2835: onClick="javascript:makeexamupload();" />
1.66 bowersj2 2836: $help{'Score_Upload_Form'}
1.58 albertel 2837: </nobr>
1.22 www 2838: </form>
1.214 www 2839: <br /><form action="/adm/coursedocs" method="post" name="newbul">
1.142 raeburn 2840: $uploadtag
1.256 albertel 2841: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2842: <nobr>
1.81 www 2843: <input name="newbulletin" type="button" value="$lt{'bull'}"
1.22 www 2844: onClick="javascript:makebulboard();" />
1.65 bowersj2 2845: $help{'Bulletin Board'}
1.58 albertel 2846: </nobr>
2847: </form>
1.214 www 2848: <br /><form action="/adm/coursedocs" method="post" name="newaboutme">
1.142 raeburn 2849: $uploadtag
1.256 albertel 2850: <input type="hidden" name="importdetail"
2851: value="$plainname=/adm/$udom/$uname/aboutme" />
1.58 albertel 2852: <nobr>
1.81 www 2853: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65 bowersj2 2854: $help{'My Personal Info'}
1.101 www 2855: </nobr>
2856: </form>
1.214 www 2857: <br /><form action="/adm/coursedocs" method="post" name="newaboutsomeone">
1.142 raeburn 2858: $uploadtag
1.256 albertel 2859: <input type="hidden" name="importdetail" value="" />
1.101 www 2860: <nobr>
2861: <input name="newaboutsomeone" type="button" value="$lt{'abou'}"
2862: onClick="javascript:makeabout();" />
1.110 raeburn 2863: </nobr>
1.182 albertel 2864: </form>
1.255 raeburn 2865: <br /><form action="/adm/coursedocs" method="post" name="newgroupfiles">
2866: $uploadtag
1.256 albertel 2867: <input type="hidden" name="importdetail"
2868: value="Group Files=/adm/$coursedom/$coursenum/aboutme" />
1.255 raeburn 2869: <nobr>
2870: <input name="newgroupfiles" type="submit" value="$lt{'grpo'}" />
2871: $help{'Group Files'}
2872: </nobr>
2873: </form>
1.142 raeburn 2874: ENDFORM
2875: }
1.174 albertel 2876: if ($env{'form.pagepath'}) {
1.142 raeburn 2877: $r->print(<<ENDBLOCK);
2878: <form action="/adm/coursedocs" method="post" name="newsmpproblem">
2879: $uploadtag
1.256 albertel 2880: <input type="hidden" name="importdetail" value="" />
1.142 raeburn 2881: <nobr>
2882: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
2883: onClick="javascript:makesmpproblem();" />$help{'Simple Problem'}
2884: </nobr>
2885: </form>
1.214 www 2886: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142 raeburn 2887: $uploadtag
1.256 albertel 2888: <input type="hidden" name="importdetail" value="" />
1.142 raeburn 2889: <nobr>
2890: <input name="newexamupload" type="button" value="$lt{'scuf'}"
2891: onClick="javascript:makeexamupload();" />
2892: $help{'Score_Upload_Form'}
2893: </nobr>
1.182 albertel 2894: </form>
1.142 raeburn 2895: ENDBLOCK
2896: }
2897: $r->print('</td></tr>'."\n".
2898: '</table>');
1.24 www 2899: $r->print('</td></tr>');
1.7 www 2900: }
2901: # ----------------------------------------------------- Supplemental documents
2902: if (!$forcestandard) {
1.116 albertel 2903: $r->print('<tr><td bgcolor="#BBBBBB">');
2904: # '<h2>'.&mt('Supplemental Course Documents').
2905: # ($allowed?' '.$help{'Supplemental'}:'').'</h2>');
1.174 albertel 2906: my $folder=$env{'form.folder'};
1.117 albertel 2907: unless ($folder=~/^supplemental/) {
1.116 albertel 2908: $folder='supplemental';
1.117 albertel 2909: }
2910: if ($folder =~ /^supplemental$/ &&
1.174 albertel 2911: $env{'form.folderpath'} =~ /^default\&/) {
2912: $env{'form.folderpath'}='supplemental&'.
1.230 albertel 2913: &escape(&mt('Supplemental '.$type.' Documents'));
1.116 albertel 2914: }
1.7 www 2915: &editor($r,$coursenum,$coursedom,$folder,$allowed);
1.8 www 2916: if ($allowed) {
1.17 www 2917: my $folderseq=
2918: '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
2919: '.sequence';
2920:
1.8 www 2921: $r->print(<<ENDSUPFORM);
1.43 www 2922: <table cellspacing=4 cellpadding=4><tr>
1.81 www 2923: <th bgcolor="#DDDDDD">$lt{'upls'}</th>
2924: <th bgcolor="#DDDDDD">$lt{'spec'}</th>
1.17 www 2925: </tr>
2926: <tr><td bgcolor="#DDDDDD">
1.10 www 2927: <form action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.59 www 2928: <input type="file" name="uploaddoc" size="40">
1.196 raeburn 2929: <br />
2930: <br />
2931: <nobr>
2932: <label>$lt{'parse'}?
2933: <input type="checkbox" name="parserflag" />
2934: </label>
2935: </nobr>
2936: <br /><br />
2937: $lt{'comment'}:<br />
1.4 www 2938: <textarea cols=50 rows=4 name='comment'>
2939: </textarea>
1.115 albertel 2940: <br />
1.174 albertel 2941: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.10 www 2942: <input type="hidden" name="cmd" value="upload_supplemental">
1.58 albertel 2943: <nobr>
1.81 www 2944: <input type="submit" value="$lt{'upld'}">
1.58 albertel 2945: $help{'Uploading_From_Harddrive'}
2946: </nobr>
2947: </form>
1.17 www 2948: </td>
2949: <td bgcolor="#DDDDDD">
1.18 www 2950: <form action="/adm/coursedocs" method="post" name="supnewfolder">
1.174 albertel 2951: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2952: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2953: <nobr>
1.17 www 2954: <input name="newfolder" type="button"
2955: onClick="javascript:makenewfolder(this.form,'$folderseq');"
1.81 www 2956: value="$lt{'newf'}" /> $help{'Adding_Folders'}
1.58 albertel 2957: </nobr>
1.17 www 2958: </form>
1.214 www 2959: <br /><form action="/adm/coursedocs" method="post" name="supnewext">
1.174 albertel 2960: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2961: <input type="hidden" name="importdetail" value="" />
1.58 albertel 2962: <nobr>
1.18 www 2963: <input name="newext" type="button"
2964: onClick="javascript:makenewext('supnewext');"
1.81 www 2965: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.58 albertel 2966: </nobr>
1.17 www 2967: </form>
1.214 www 2968: <br /><form action="/adm/coursedocs" method="post" name="supnewsyl">
1.174 albertel 2969: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2970: <input type="hidden" name="importdetail"
2971: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.58 albertel 2972: <nobr>
1.81 www 2973: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65 bowersj2 2974: $help{'Syllabus'}
1.58 albertel 2975: </nobr>
2976: </form>
1.214 www 2977: <br /><form action="/adm/coursedocs" method="post" name="subnewaboutme">
1.174 albertel 2978: <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
1.256 albertel 2979: <input type="hidden" name="importdetail"
2980: value="$plainname=/adm/$udom/$uname/aboutme" />
1.58 albertel 2981: <nobr>
1.81 www 2982: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65 bowersj2 2983: $help{'My Personal Info'}
1.58 albertel 2984: </nobr>
2985: </form>
1.17 www 2986: </td></tr>
1.24 www 2987: </table></td></tr>
1.8 www 2988: ENDSUPFORM
2989: }
1.7 www 2990: }
1.18 www 2991: if ($allowed) {
1.182 albertel 2992: $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 2993: }
1.24 www 2994: $r->print('</table>');
1.19 www 2995: } else {
1.188 raeburn 2996: unless ($upload_result eq 'phasetwo') {
1.19 www 2997: # -------------------------------------------------------- This is showdoc mode
1.188 raeburn 2998: $r->print("<h1>".&mt('Uploaded Document').' - '.
1.141 albertel 2999: &Apache::lonnet::gettitle($r->uri).'</h1><p>'.
1.81 www 3000: &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><p><table>".
1.188 raeburn 3001: &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table></p>');
3002: }
1.19 www 3003: }
1.26 www 3004: }
1.224 albertel 3005: $r->print(&Apache::loncommon::end_page());
1.26 www 3006: return OK;
1.1 www 3007: }
3008:
1.224 albertel 3009:
3010: sub editing_js {
3011: my ($udom,$uname) = @_;
3012: my $now = time();
3013:
3014: return <<ENDNEWSCRIPT;
3015: function makenewfolder(targetform,folderseq) {
3016: var foldername=prompt('Name of New Folder','New Folder');
3017: if (foldername) {
1.236 albertel 3018: targetform.importdetail.value=escape(foldername)+"="+folderseq;
1.224 albertel 3019: targetform.submit();
3020: }
3021: }
3022:
3023: function makenewpage(targetform,folderseq) {
3024: var pagename=prompt('Name of New Page','New Page');
3025: if (pagename) {
1.236 albertel 3026: targetform.importdetail.value=escape(pagename)+"="+folderseq;
1.224 albertel 3027: targetform.submit();
3028: }
3029: }
3030:
3031: function makenewext(targetname) {
3032: this.document.forms.extimport.useform.value=targetname;
3033: window.open('/adm/rat/extpickframe.html');
3034: }
3035:
3036: function makeexamupload() {
3037: var title=prompt('Listed Title for the Uploaded Score');
3038: if (title) {
3039: this.document.forms.newexamupload.importdetail.value=
1.236 albertel 3040: escape(title)+'=/res/lib/templates/examupload.problem';
1.224 albertel 3041: this.document.forms.newexamupload.submit();
3042: }
3043: }
3044:
3045: function makesmppage() {
3046: var title=prompt('Listed Title for the Page');
3047: if (title) {
3048: this.document.forms.newsmppg.importdetail.value=
1.236 albertel 3049: escape(title)+'=/adm/$udom/$uname/$now/smppg';
1.224 albertel 3050: this.document.forms.newsmppg.submit();
3051: }
3052: }
3053:
3054: function makesmpproblem() {
3055: var title=prompt('Listed Title for the Problem');
3056: if (title) {
3057: this.document.forms.newsmpproblem.importdetail.value=
1.236 albertel 3058: escape(title)+'=/res/lib/templates/simpleproblem.problem';
1.224 albertel 3059: this.document.forms.newsmpproblem.submit();
3060: }
3061: }
3062:
3063: function makedropbox() {
3064: var title=prompt('Listed Title for the Drop Box');
3065: if (title) {
3066: this.document.forms.newdropbox.importdetail.value=
1.236 albertel 3067: escape(title)+'=/res/lib/templates/DropBox.problem';
1.224 albertel 3068: this.document.forms.newdropbox.submit();
3069: }
3070: }
3071:
3072: function makebulboard() {
3073: var title=prompt('Listed Title for the Bulletin Board');
3074: if (title) {
3075: this.document.forms.newbul.importdetail.value=
1.236 albertel 3076: escape(title)+'=/adm/$udom/$uname/$now/bulletinboard';
1.224 albertel 3077: this.document.forms.newbul.submit();
3078: }
3079: }
3080:
3081: function makeabout() {
1.236 albertel 3082: var user=prompt("Enter user:domain for User's 'About Me' Page");
1.224 albertel 3083: if (user) {
3084: var comp=new Array();
1.236 albertel 3085: comp=user.split(':');
1.224 albertel 3086: if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) {
3087: if ((comp[0]) && (comp[1])) {
3088: this.document.forms.newaboutsomeone.importdetail.value=
1.236 albertel 3089: 'About '+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme';
1.224 albertel 3090: this.document.forms.newaboutsomeone.submit();
3091: } else {
1.236 albertel 3092: alert("Not a valid user:domain");
1.224 albertel 3093: }
3094: } else {
1.236 albertel 3095: alert("Please enter both user and domain in the format user:domain");
1.224 albertel 3096: }
3097: }
3098: }
3099:
3100: function makeims() {
3101: var caller = document.forms.ims.folder.value;
3102: var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one";
3103: newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes");
3104: newWindow.location.href = newlocation;
3105: }
3106:
3107:
3108: function finishpick() {
3109: var title=this.document.forms.extimport.title.value;
3110: var url=this.document.forms.extimport.url.value;
3111: var form=this.document.forms.extimport.useform.value;
3112: eval
3113: ('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+
3114: '";this.document.forms.'+form+'.submit();');
3115: }
3116:
3117: function changename(folderpath,index,oldtitle,container,pagesymb) {
3118: var title=prompt('New Title',oldtitle);
3119: if (title) {
3120: this.document.forms.renameform.title.value=title;
3121: this.document.forms.renameform.cmd.value='rename_'+index;
3122: if (container == 'sequence') {
3123: this.document.forms.renameform.folderpath.value=folderpath;
3124: }
3125: if (container == 'page') {
3126: this.document.forms.renameform.pagepath.value=folderpath;
3127: this.document.forms.renameform.pagesymb.value=pagesymb;
3128: }
3129: this.document.forms.renameform.submit();
3130: }
3131: }
3132:
3133: function removeres(folderpath,index,oldtitle,container,pagesymb) {
3134: if (confirm('WARNING: Removing a resource makes associated grades and scores inaccessible!\\nRemove "'+oldtitle+'"?')) {
3135: this.document.forms.renameform.cmd.value='del_'+index;
3136: if (container == 'sequence') {
3137: this.document.forms.renameform.folderpath.value=folderpath;
3138: }
3139: if (container == 'page') {
3140: this.document.forms.renameform.pagepath.value=folderpath;
3141: this.document.forms.renameform.pagesymb.value=pagesymb;
3142: }
3143: this.document.forms.renameform.submit();
3144: }
3145: }
3146:
3147: function cutres(folderpath,index,oldtitle,container,pagesymb) {
3148: if (confirm('WARNING: Cutting a resource makes associated grades and scores inaccessible!\\nGrades remain inaccessible if resource is pasted into another folder.\\nCut "'+oldtitle+'"?')) {
3149: this.document.forms.renameform.cmd.value='cut_'+index;
3150: this.document.forms.renameform.markcopy.value=index;
3151: if (container == 'sequence') {
3152: this.document.forms.renameform.folderpath.value=folderpath;
3153: }
3154: if (container == 'page') {
3155: this.document.forms.renameform.pagepath.value=folderpath;
3156: this.document.forms.renameform.pagesymb.value=pagesymb;
3157: }
3158: this.document.forms.renameform.submit();
3159: }
3160: }
3161:
3162: function markcopy(folderpath,index,oldtitle,container,pagesymb) {
3163: this.document.forms.renameform.markcopy.value=index;
3164: if (container == 'sequence') {
3165: this.document.forms.renameform.folderpath.value=folderpath;
3166: }
3167: if (container == 'page') {
3168: this.document.forms.renameform.pagepath.value=folderpath;
3169: this.document.forms.renameform.pagesymb.value=pagesymb;
3170: }
3171: this.document.forms.renameform.submit();
3172: }
3173:
3174: ENDNEWSCRIPT
3175: }
1.1 www 3176: 1;
3177: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>