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