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