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