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