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