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