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