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