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