Annotation of loncom/interface/londocs.pm, revision 1.325.2.9
1.1 www 1: # The LearningOnline Network
1.2 www 2: # Documents
1.1 www 3: #
1.325.2.9! raeburn 4: # $Id: londocs.pm,v 1.325.2.8 2010/02/10 17:41:40 raeburn Exp $
1.1 www 5: #
1.3 www 6: # Copyright Michigan State University Board of Trustees
1.1 www 7: #
1.3 www 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
1.1 www 9: #
1.3 www 10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
1.1 www 14: #
1.3 www 15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
1.315 jms 29:
30:
1.2 www 31: package Apache::londocs;
1.1 www 32:
33: use strict;
1.28 www 34: use Apache::Constants qw(:common :http);
1.158 raeburn 35: use Apache::imsexport;
1.4 www 36: use Apache::lonnet;
37: use Apache::loncommon;
1.245 albertel 38: use LONCAPA::map();
39: use Apache::lonratedt();
1.15 www 40: use Apache::lonxml;
1.244 albertel 41: use Apache::lonclonecourse;
1.138 raeburn 42: use Apache::lonnavmaps;
1.38 www 43: use HTML::Entities;
1.27 www 44: use GDBM_File;
1.81 www 45: use Apache::lonlocal;
1.143 raeburn 46: use Cwd;
1.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.8 raeburn 268: return '<div><input type="submit" name="exportcourse"'
1.325.2.4 raeburn 269: .' value="'.&mt('IMS Export').'"'
1.325.2.6 raeburn 270: .' title="'.&mt('Export '.$crstype.' to IMS Package').'" />'.
1.325.2.8 raeburn 271: &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'</div>';
1.138 raeburn 272: }
273:
1.315 jms 274:
275:
1.138 raeburn 276: sub exportcourse {
277: my $r=shift;
1.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,'"<>&\'');
1.325.2.7 raeburn 1761: $renametitle = &HTML::Entities::encode($renametitle,'"<>&\'');
1.281 albertel 1762: $title='<i>'.&Apache::lonlocal::locallocaltime($time).'</i> '.
1763: $name.': <br />'.$foldertitle;
1764: }
1765: if (wantarray) {
1766: return ($title,$foldertitle,$renametitle);
1767: }
1768: return $title;
1769: }
1770:
1.8 www 1771: # --------------------------------------------------------------- An entry line
1772:
1773: sub entryline {
1.325.2.6 raeburn 1774: my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$crstype)=@_;
1.281 albertel 1775:
1776: my ($foldertitle,$pagetitle,$renametitle);
1777: if (&is_supplemental_title($title)) {
1778: ($title,$foldertitle,$renametitle) = &parse_supplemental_title($title);
1779: $pagetitle = $foldertitle;
1780: } else {
1781: $title=&HTML::Entities::encode($title,'"<>&\'');
1782: $renametitle=$title;
1783: $foldertitle=$title;
1784: $pagetitle=$title;
1785: }
1786:
1.245 albertel 1787: my $orderidx=$LONCAPA::map::order[$index];
1.281 albertel 1788:
1789:
1.222 albertel 1790: $renametitle=~s/\\/\\\\/g;
1.38 www 1791: $renametitle=~s/\"\;/\\\"/g;
1.286 albertel 1792: $renametitle=~s/ /%20/g;
1.8 www 1793: my $line='<tr>';
1.286 albertel 1794: my ($form_start,$form_end);
1.8 www 1795: # Edit commands
1.280 albertel 1796: my ($container, $type, $esc_path, $path, $symb);
1.174 albertel 1797: if ($env{'form.folderpath'}) {
1.280 albertel 1798: $type = 'folder';
1.142 raeburn 1799: $container = 'sequence';
1.282 albertel 1800: $esc_path=&escape($env{'form.folderpath'});
1801: $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.174 albertel 1802: # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"');
1.120 www 1803: }
1.174 albertel 1804: if ($env{'form.pagepath'}) {
1.280 albertel 1805: $type = $container = 'page';
1806: $esc_path=&escape($path = $env{'form.pagepath'});
1.282 albertel 1807: $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"');
1.280 albertel 1808: $symb=&escape($env{'form.pagesymb'});
1.142 raeburn 1809: }
1.168 www 1810: my $cpinfo='';
1.109 albertel 1811: if ($allowed) {
1.123 www 1812: my $incindex=$index+1;
1813: my $selectbox='';
1.168 www 1814: if (($folder!~/^supplemental/) &&
1.245 albertel 1815: ($#LONCAPA::map::order>0) &&
1.168 www 1816: ((split(/\:/,
1.245 albertel 1817: $LONCAPA::map::resources[$LONCAPA::map::order[0]]))[1]
1.168 www 1818: ne '') &&
1819: ((split(/\:/,
1.245 albertel 1820: $LONCAPA::map::resources[$LONCAPA::map::order[1]]))[1]
1.168 www 1821: ne '')) {
1.123 www 1822: $selectbox=
1.124 www 1823: '<input type="hidden" name="currentpos" value="'.$incindex.'" />'.
1.123 www 1824: '<select name="newpos" onChange="this.form.submit()">';
1.245 albertel 1825: for (my $i=1;$i<=$#LONCAPA::map::order+1;$i++) {
1.123 www 1826: if ($i==$incindex) {
1.325.2.1 raeburn 1827: $selectbox.='<option value="" selected="selected">('.$i.')</option>';
1.123 www 1828: } else {
1829: $selectbox.='<option value="'.$i.'">'.$i.'</option>';
1830: }
1831: }
1832: $selectbox.='</select>';
1833: }
1.119 www 1834: my %lt=&Apache::lonlocal::texthash(
1835: 'up' => 'Move Up',
1.109 albertel 1836: 'dw' => 'Move Down',
1837: 'rm' => 'Remove',
1.171 www 1838: 'ct' => 'Cut',
1.168 www 1839: 'rn' => 'Rename',
1840: 'cp' => 'Copy');
1.211 www 1841: my $nocopy=0;
1.268 www 1842: my $nocut=0;
1.211 www 1843: if ($url=~/\.(page|sequence)$/) {
1.289 albertel 1844: if ($url =~ m{/res/}) {
1845: # no copy for published maps
1846: $nocopy = 1;
1847: } else {
1.320 raeburn 1848: foreach my $item (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url),1)) {
1849: my ($title,$url,$ext,$type)=split(/\:/,$item);
1.289 albertel 1850: if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) {
1851: $nocopy=1;
1852: last;
1853: }
1.211 www 1854: }
1855: }
1856: }
1.268 www 1857: if ($url=~/^\/res\/lib\/templates\//) {
1858: $nocopy=1;
1859: $nocut=1;
1860: }
1.211 www 1861: my $copylink=' ';
1.267 www 1862: my $cutlink=' ';
1.280 albertel 1863:
1.291 albertel 1864: my $skip_confirm = 0;
1865: if ( $folder =~ /^supplemental/
1866: || ($url =~ m{( /smppg$
1867: |/syllabus$
1868: |/aboutme$
1869: |/navmaps$
1870: |/bulletinboard$
1871: |\.html$
1872: |^/adm/wrapper/ext)}x)) {
1873: $skip_confirm = 1;
1874: }
1875:
1.280 albertel 1876: if (!$nocopy) {
1877: $copylink=(<<ENDCOPY);
1.284 albertel 1878: <a href='javascript:markcopy("$esc_path","$index","$renametitle","$container","$symb","$folder");' class="LC_docs_copy">$lt{'cp'}</a>
1.211 www 1879: ENDCOPY
1.280 albertel 1880: }
1881: if (!$nocut) {
1882: $cutlink=(<<ENDCUT);
1.291 albertel 1883: <a href='javascript:cutres("$esc_path","$index","$renametitle","$container","$symb","$folder",$skip_confirm);' class="LC_docs_cut">$lt{'ct'}</a>
1.267 www 1884: ENDCUT
1.280 albertel 1885: }
1.286 albertel 1886: $form_start = (<<END);
1887: <form action="/adm/coursedocs" method="post">
1.280 albertel 1888: <input type="hidden" name="${type}path" value="$path" />
1889: <input type="hidden" name="${type}symb" value="$symb" />
1890: <input type="hidden" name="setparms" value="$orderidx" />
1891: <input type="hidden" name="changeparms" value="0" />
1.286 albertel 1892: END
1893: $form_end = '</form>';
1894: $line.=(<<END);
1.280 albertel 1895: <td>
1.285 albertel 1896: <table class="LC_docs_entry_move">
1.280 albertel 1897: <tr>
1.285 albertel 1898: <td>
1.282 albertel 1899: <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 1900: </td>
1901: </tr>
1902: <tr>
1.285 albertel 1903: <td>
1.282 albertel 1904: <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 1905: </td>
1906: </tr>
1907: </table>
1908: </td>
1909: <td>
1.286 albertel 1910: $form_start
1.280 albertel 1911: $selectbox
1.286 albertel 1912: $form_end
1.280 albertel 1913: </td>
1.285 albertel 1914: <td class="LC_docs_entry_commands">
1.291 albertel 1915: <a href='javascript:removeres("$esc_path","$index","$renametitle","$container","$symb",$skip_confirm);' class="LC_docs_remove">$lt{'rm'}</a>
1.267 www 1916: $cutlink
1.284 albertel 1917: <a href='javascript:changename("$esc_path","$index","$renametitle","$container","$symb");' class="LC_docs_rename">$lt{'rn'}</a>
1.211 www 1918: $copylink
1.280 albertel 1919: </td>
1.142 raeburn 1920: END
1.280 albertel 1921:
1.8 www 1922: }
1.16 www 1923: # Figure out what kind of a resource this is
1924: my ($extension)=($url=~/\.(\w+)$/);
1925: my $uploaded=($url=~/^\/*uploaded\//);
1.97 albertel 1926: my $icon=&Apache::loncommon::icon($url);
1.17 www 1927: my $isfolder=0;
1.142 raeburn 1928: my $ispage=0;
1.114 albertel 1929: my $folderarg;
1.142 raeburn 1930: my $pagearg;
1931: my $pagefile;
1.16 www 1932: if ($uploaded) {
1.135 albertel 1933: if ($extension eq 'sequence') {
1934: $icon=$iconpath.'/folder_closed.gif';
1.264 albertel 1935: $url=~/\Q$coursenum\E\/([\/\w]+)\.sequence$/;
1.135 albertel 1936: $url='/adm/coursedocs?';
1937: $folderarg=$1;
1938: $isfolder=1;
1.142 raeburn 1939: } elsif ($extension eq 'page') {
1940: $icon=$iconpath.'/page.gif';
1.264 albertel 1941: $url=~/\Q$coursenum\E\/([\/\w]+)\.page$/;
1.142 raeburn 1942: $pagearg=$1;
1943: $url='/adm/coursedocs?';
1944: $ispage=1;
1.135 albertel 1945: } else {
1946: &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
1947: }
1.16 www 1948: }
1.287 albertel 1949:
1950: my $orig_url = $url;
1.325.2.1 raeburn 1951: $orig_url=~s{http(:|:)//https(:|:)//}{https$2//};
1.287 albertel 1952: my $external = ($url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/});
1.142 raeburn 1953: if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) {
1.113 albertel 1954: my $symb=&Apache::lonnet::symbclean(
1.50 www 1955: &Apache::lonnet::declutter('uploaded/'.
1.174 albertel 1956: $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
1957: $env{'course.'.$env{'request.course.id'}.'.num'}.'/'.$folder.
1.50 www 1958: '.sequence').
1959: '___'.$residx.'___'.
1.113 albertel 1960: &Apache::lonnet::declutter($url));
1961: (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
1962: $url=&Apache::lonnet::clutter($url);
1.127 albertel 1963: if ($url=~/^\/*uploaded\//) {
1964: $url=~/\.(\w+)$/;
1965: my $embstyle=&Apache::loncommon::fileembstyle($1);
1966: if (($embstyle eq 'img') || ($embstyle eq 'emb')) {
1967: $url='/adm/wrapper'.$url;
1968: } elsif ($embstyle eq 'ssi') {
1969: #do nothing with these
1970: } elsif ($url!~/\.(sequence|page)$/) {
1971: $url='/adm/coursedocs/showdoc'.$url;
1972: }
1.145 albertel 1973: } elsif ($url=~m|^/ext/|) {
1974: $url='/adm/wrapper'.$url;
1.287 albertel 1975: $external = 1;
1.127 albertel 1976: }
1.241 www 1977: if (&Apache::lonnet::symbverify($symb,$url)) {
1978: $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
1979: } else {
1980: $url='';
1981: }
1.152 albertel 1982: if ($container eq 'page') {
1.174 albertel 1983: my $symb=$env{'form.pagesymb'};
1.152 albertel 1984:
1985: $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
1.228 www 1986: $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb);
1.152 albertel 1987: }
1.50 www 1988: }
1.296 albertel 1989: my ($parameterset,$rand_order_text) = (' ', ' ');
1.216 albertel 1990: if ($isfolder || $extension eq 'sequence') {
1.228 www 1991: my $foldername=&escape($foldertitle);
1.174 albertel 1992: my $folderpath=$env{'form.folderpath'};
1.114 albertel 1993: if ($folderpath) { $folderpath.='&' };
1.242 www 1994: # Append randompick number, hidden, and encrypted with ":" to foldername,
1995: # so it gets transferred between levels
1.245 albertel 1996: $folderpath.=$folderarg.'&'.$foldername.':'.(&LONCAPA::map::getparameter($orderidx,
1.242 www 1997: 'parameter_randompick'))[0]
1.245 albertel 1998: .':'.((&LONCAPA::map::getparameter($orderidx,
1.242 www 1999: 'parameter_hiddenresource'))[0]=~/^yes$/i)
1.245 albertel 2000: .':'.((&LONCAPA::map::getparameter($orderidx,
1.296 albertel 2001: 'parameter_encrypturl'))[0]=~/^yes$/i)
2002: .':'.((&LONCAPA::map::getparameter($orderidx,
2003: 'parameter_randomorder'))[0]=~/^yes$/i);
1.228 www 2004: $url.='folderpath='.&escape($folderpath).$cpinfo;
1.147 matthew 2005: $parameterset='<label>'.&mt('Randomly Pick: ').
1.292 albertel 2006: '<input type="text" size="4" onChange="this.form.changeparms.value='."'randompick'".';this.form.submit()" name="randompick_'.$orderidx.'" value="'.
1.245 albertel 2007: (&LONCAPA::map::getparameter($orderidx,
1.147 matthew 2008: 'parameter_randompick'))[0].
1.165 www 2009: '" />'.
1.285 albertel 2010: '<a href="javascript:void(0)">'.&mt('Save').'</a></label>';
1.296 albertel 2011: my $ro_set=
2012: ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
2013: $rand_order_text ='
1.325.2.2 raeburn 2014: <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 2015: }
1.142 raeburn 2016: if ($ispage) {
1.228 www 2017: my $pagename=&escape($pagetitle);
1.142 raeburn 2018: my $pagepath;
1.174 albertel 2019: my $folderpath=$env{'form.folderpath'};
1.142 raeburn 2020: if ($folderpath) { $pagepath = $folderpath.'&' };
2021: $pagepath.=$pagearg.'&'.$pagename;
1.174 albertel 2022: my $symb=$env{'form.pagesymb'};
1.152 albertel 2023: if (!$symb) {
2024: my $path='uploaded/'.
1.174 albertel 2025: $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'.
2026: $env{'course.'.$env{'request.course.id'}.'.num'}.'/';
1.152 albertel 2027: $symb=&Apache::lonnet::encode_symb($path.$folder.'.sequence',
2028: $residx,
2029: $path.$pagearg.'.page');
2030: }
1.228 www 2031: $url.='pagepath='.&escape($pagepath).
1.282 albertel 2032: '&pagesymb='.&escape($symb).$cpinfo;
1.142 raeburn 2033: }
1.287 albertel 2034: if ($external) {
2035: my $form = ($folder =~ /^default/)? 'newext' : 'supnewext';
2036: $external = ' <a class="LC_docs_ext_edit" href="javascript:edittext(\''.$form.'\',\''.$residx.'\',\''.&escape($title).'\',\''.&escape($orig_url).'\');" >'.&mt('Edit').'</a>';
2037: } else {
2038: undef($external);
2039: }
1.325.2.6 raeburn 2040: my $reinit;
2041: if ($crstype eq 'Community') {
2042: $reinit = &mt('(re-initialize community to access)');
2043: } else {
2044: $reinit = &mt('(re-initialize course to access)');
2045: }
1.285 albertel 2046: $line.='
2047: <td class="LC_docs_entry_icon">
1.287 albertel 2048: '.($url?'<a href="'.$url.'">':'').'<img src="'.$icon.'" alt="" class="LC_icon" />'.($url?'</a>':'').'
1.285 albertel 2049: </td>
2050: <td class="LC_docs_entry_title">
1.325.2.6 raeburn 2051: '.($url?"<a href=\"$url\">":'').$title.($url?'</a>':' <span class="LC_docs_reinit_warn">'.$reinit.'</span>').$external."
1.285 albertel 2052: </td>";
1.120 www 2053: if (($allowed) && ($folder!~/^supplemental/)) {
2054: my %lt=&Apache::lonlocal::texthash(
2055: 'hd' => 'Hidden',
1.165 www 2056: 'ec' => 'URL hidden');
1.122 www 2057: my $enctext=
1.325.2.1 raeburn 2058: ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':'');
1.122 www 2059: my $hidtext=
1.325.2.1 raeburn 2060: ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':'');
1.120 www 2061: $line.=(<<ENDPARMS);
1.285 albertel 2062: <td class="LC_docs_entry_parameter">
1.286 albertel 2063: $form_start
1.325.2.2 raeburn 2064: <label><input type="checkbox" name="hiddenresource_$orderidx" onclick="this.form.changeparms.value='hiddenresource';this.form.submit()" $hidtext /> $lt{'hd'}</label>
1.286 albertel 2065: $form_end
1.285 albertel 2066: </td>
2067: <td class="LC_docs_entry_parameter">
1.286 albertel 2068: $form_start
1.325.2.2 raeburn 2069: <label><input type="checkbox" name="encrypturl_$orderidx" onclick="this.form.changeparms.value='encrypturl';this.form.submit()" $enctext /> $lt{'ec'}</label>
1.286 albertel 2070: $form_end
1.285 albertel 2071: </td>
1.296 albertel 2072: <td class="LC_docs_entry_parameter">$form_start $rand_order_text $form_end</td>
1.286 albertel 2073: <td class="LC_docs_entry_parameter">$form_start $parameterset $form_end</td>
1.120 www 2074: ENDPARMS
1.119 www 2075: }
1.286 albertel 2076: $line.="</tr>";
1.8 www 2077: return $line;
2078: }
2079:
1.315 jms 2080: =pod
2081:
2082: =item tiehash()
2083:
2084: tie the hash
2085:
2086: =cut
1.27 www 2087:
2088: sub tiehash {
1.136 albertel 2089: my ($mode)=@_;
1.27 www 2090: $hashtied=0;
1.174 albertel 2091: if ($env{'request.course.fn'}) {
1.136 albertel 2092: if ($mode eq 'write') {
1.174 albertel 2093: if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136 albertel 2094: &GDBM_WRCREAT(),0640)) {
2095: $hashtied=2;
2096: }
2097: } else {
1.174 albertel 2098: if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
1.136 albertel 2099: &GDBM_READER(),0640)) {
1.27 www 2100: $hashtied=1;
1.136 albertel 2101: }
2102: }
1.27 www 2103: }
2104: }
2105:
2106: sub untiehash {
2107: if ($hashtied) { untie %hash; }
2108: $hashtied=0;
1.221 albertel 2109: return OK;
1.27 www 2110: }
2111:
1.315 jms 2112:
2113:
1.29 www 2114:
2115: sub checkonthis {
2116: my ($r,$url,$level,$title)=@_;
1.228 www 2117: $url=&unescape($url);
1.29 www 2118: $alreadyseen{$url}=1;
2119: $r->rflush();
1.41 www 2120: if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
1.108 albertel 2121: $r->print("\n<br />");
1.313 bisitz 2122: if ($level==0) {
2123: $r->print("<br />");
2124: }
1.29 www 2125: for (my $i=0;$i<=$level*5;$i++) {
2126: $r->print(' ');
2127: }
2128: $r->print('<a href="'.$url.'" target="cat">'.
2129: ($title?$title:$url).'</a> ');
2130: if ($url=~/^\/res\//) {
2131: my $result=&Apache::lonnet::repcopy(
2132: &Apache::lonnet::filelocation('',$url));
1.172 raeburn 2133: if ($result eq 'ok') {
1.313 bisitz 2134: $r->print('<span class="LC_success">'.&mt('ok').'</span>');
1.29 www 2135: $r->rflush();
1.34 www 2136: &Apache::lonnet::countacc($url);
2137: $url=~/\.(\w+)$/;
2138: if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
2139: $r->print('<br />');
2140: $r->rflush();
2141: for (my $i=0;$i<=$level*5;$i++) {
2142: $r->print(' ');
2143: }
1.313 bisitz 2144: $r->print('- '.&mt('Rendering:').' ');
1.170 www 2145: my ($errorcount,$warningcount)=split(/:/,
2146: &Apache::lonnet::ssi_body($url,
1.173 albertel 2147: ('grade_target'=>'web',
2148: 'return_only_error_and_warning_counts' => 1)));
1.170 www 2149: if (($errorcount) ||
2150: ($warningcount)) {
2151: if ($errorcount) {
1.325.2.2 raeburn 2152: $r->print('<img src="/adm/lonMisc/bomb.gif" alt="'.&mt('bomb').'" /><span class="LC_error">'.
1.313 bisitz 2153: &mt('[quant,_1,error]',$errorcount).'</span>');
1.34 www 2154: }
1.170 www 2155: if ($warningcount) {
1.283 albertel 2156: $r->print('<span class="LC_warning">'.
1.313 bisitz 2157: &mt('[quant,_1,warning]',$warningcount).'</span>');
1.34 www 2158: }
2159: } else {
1.283 albertel 2160: $r->print('<span class="LC_success">'.&mt('ok').'</span>');
1.34 www 2161: }
2162: $r->rflush();
2163: }
1.29 www 2164: my $dependencies=
2165: &Apache::lonnet::metadata($url,'dependencies');
1.320 raeburn 2166: foreach my $dep (split(/\,/,$dependencies)) {
2167: if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) {
2168: &checkonthis($r,$dep,$level+1);
1.29 www 2169: }
2170: }
1.172 raeburn 2171: } elsif ($result eq 'unavailable') {
1.283 albertel 2172: $r->print('<span class="LC_error">'.&mt('connection down').'</span>');
1.172 raeburn 2173: } elsif ($result eq 'not_found') {
1.100 www 2174: unless ($url=~/\$/) {
1.313 bisitz 2175: $r->print('<span class="LC_error">'.&mt('not found').'</b></span>');
1.100 www 2176: } else {
1.325.2.1 raeburn 2177: $r->print('<span class="LC_error">'.&mt('unable to verify variable URL').'</span>');
1.100 www 2178: }
1.29 www 2179: } else {
1.283 albertel 2180: $r->print('<span class="LC_error">'.&mt('access denied').'</span>');
1.29 www 2181: }
1.313 bisitz 2182: }
2183: }
1.29 www 2184: }
2185:
1.1 www 2186:
1.315 jms 2187:
2188: =pod
2189:
2190: =item list_symbs()
2191:
2192: List Symbs
2193:
2194: =cut
2195:
1.208 albertel 2196: sub list_symbs {
1.224 albertel 2197: my ($r) = @_;
2198:
1.325.2.6 raeburn 2199: my $crstype = &Apache::loncommon::course_type();
1.224 albertel 2200: $r->print(&Apache::loncommon::start_page('Symb List'));
1.257 www 2201: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Symb List'));
1.224 albertel 2202: my $navmap = Apache::lonnavmaps::navmap->new();
1.325 raeburn 2203: if (!defined($navmap)) {
2204: $r->print('<h2>'.&mt('Retrieval of List Failed').'</h2>'.
2205: '<div class="LC_error">'.
2206: &mt('Unable to retrieve information about course contents').
2207: '</div>');
1.325.2.6 raeburn 2208: &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
1.325 raeburn 2209: } else {
2210: $r->print("<pre>\n");
2211: foreach my $res ($navmap->retrieveResources()) {
2212: $r->print($res->compTitle()."\t".$res->symb()."\n");
2213: }
2214: $r->print("\n</pre>\n");
1.224 albertel 2215: }
2216: $r->print('<a href="/adm/coursedocs">'.&mt('Return to DOCS').'</a>');
1.208 albertel 2217: }
2218:
2219:
1.75 www 2220: sub verifycontent {
1.224 albertel 2221: my ($r) = @_;
1.325.2.6 raeburn 2222: my $crstype = &Apache::loncommon::course_type();
1.26 www 2223: my $loaderror=&Apache::lonnet::overloaderror($r);
2224: if ($loaderror) { return $loaderror; }
1.325.2.6 raeburn 2225: $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Documents'));
2226: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Documents'));
1.27 www 2227: $hashtied=0;
1.30 www 2228: undef %alreadyseen;
2229: %alreadyseen=();
1.27 www 2230: &tiehash();
1.320 raeburn 2231: foreach my $key (keys(%hash)) {
2232: if ($hash{$key}=~/\.(page|sequence)$/) {
2233: if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) {
1.283 albertel 2234: $r->print('<hr /><span class="LC_error">'.
1.325.2.6 raeburn 2235: &mt('The following sequence or page is included more than once in your '.$crstype.': ').
1.320 raeburn 2236: &unescape($hash{$key}).'</span><br />'.
1.140 www 2237: &mt('Note that grading records for problems included in this sequence or folder will overlap.<hr />'));
2238: }
2239: }
1.320 raeburn 2240: if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) {
2241: &checkonthis($r,$hash{$key},0,$hash{'title_'.$1});
1.27 www 2242: }
2243: }
2244: &untiehash();
1.108 albertel 2245: $r->print('<h1>'.&mt('Done').'.</h1>'.'<a href="/adm/coursedocs">'.
2246: &mt('Return to DOCS').'</a>');
1.75 www 2247: }
2248:
2249:
1.192 www 2250: sub devalidateversioncache {
2251: my $src=shift;
2252: &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
2253: &Apache::lonnet::clutter($src));
2254: }
2255:
1.75 www 2256: sub checkversions {
1.224 albertel 2257: my ($r) = @_;
1.325.2.6 raeburn 2258: my $crstype = &Apache::loncommon::course_type();
2259: $r->print(&Apache::loncommon::start_page("Check $crstype Document Versions"));
2260: $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Document Versions"));
1.89 www 2261: my $header='';
2262: my $startsel='';
2263: my $monthsel='';
2264: my $weeksel='';
2265: my $daysel='';
2266: my $allsel='';
2267: my %changes=();
2268: my $starttime=0;
1.91 www 2269: my $haschanged=0;
1.92 www 2270: my %setversions=&Apache::lonnet::dump('resourceversions',
1.174 albertel 2271: $env{'course.'.$env{'request.course.id'}.'.domain'},
2272: $env{'course.'.$env{'request.course.id'}.'.num'});
1.92 www 2273:
2274: $hashtied=0;
2275: &tiehash();
2276: my %newsetversions=();
1.174 albertel 2277: if ($env{'form.setmostrecent'}) {
1.91 www 2278: $haschanged=1;
1.320 raeburn 2279: foreach my $key (keys(%hash)) {
2280: if ($key=~/^ids\_(\/res\/.+)$/) {
1.93 www 2281: $newsetversions{$1}='mostrecent';
1.192 www 2282: &devalidateversioncache($1);
1.92 www 2283: }
2284: }
1.174 albertel 2285: } elsif ($env{'form.setcurrent'}) {
1.91 www 2286: $haschanged=1;
1.320 raeburn 2287: foreach my $key (keys(%hash)) {
2288: if ($key=~/^ids\_(\/res\/.+)$/) {
1.93 www 2289: my $getvers=&Apache::lonnet::getversion($1);
2290: if ($getvers>0) {
2291: $newsetversions{$1}=$getvers;
1.192 www 2292: &devalidateversioncache($1);
1.93 www 2293: }
1.92 www 2294: }
2295: }
1.174 albertel 2296: } elsif ($env{'form.setversions'}) {
1.91 www 2297: $haschanged=1;
1.320 raeburn 2298: foreach my $key (keys(%env)) {
2299: if ($key=~/^form\.set_version_(.+)$/) {
1.92 www 2300: my $src=$1;
1.320 raeburn 2301: if (($env{$key}) && ($env{$key} ne $setversions{$src})) {
2302: $newsetversions{$src}=$env{$key};
1.192 www 2303: &devalidateversioncache($src);
1.92 www 2304: }
2305: }
2306: }
1.91 www 2307: }
2308: if ($haschanged) {
1.92 www 2309: if (&Apache::lonnet::put('resourceversions',\%newsetversions,
1.174 albertel 2310: $env{'course.'.$env{'request.course.id'}.'.domain'},
2311: $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {
1.272 albertel 2312: $r->print('<h1>'.&mt('Your Version Settings have been Saved').'</h1>');
1.92 www 2313: } else {
1.283 albertel 2314: $r->print('<h1><span class="LC_error">'.&mt('An Error Occured while Attempting to Save your Version Settings').'</span></h1>');
1.92 www 2315: }
1.136 albertel 2316: &mark_hash_old();
1.91 www 2317: }
1.136 albertel 2318: &changewarning($r,'');
1.174 albertel 2319: if ($env{'form.timerange'} eq 'all') {
1.89 www 2320: # show all documents
1.325.2.6 raeburn 2321: $header=&mt('All Documents in '.$crstype);
1.91 www 2322: $allsel=1;
1.320 raeburn 2323: foreach my $key (keys(%hash)) {
2324: if ($key=~/^ids\_(\/res\/.+)$/) {
1.90 www 2325: my $src=$1;
2326: $changes{$src}=1;
2327: }
2328: }
1.89 www 2329: } else {
2330: # show documents which changed
2331: %changes=&Apache::lonnet::dump
1.174 albertel 2332: ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
2333: $env{'course.'.$env{'request.course.id'}.'.num'});
1.320 raeburn 2334: my $firstkey=(keys(%changes))[0];
1.89 www 2335: unless ($firstkey=~/^error\:/) {
1.174 albertel 2336: unless ($env{'form.timerange'}) {
2337: $env{'form.timerange'}=604800;
1.89 www 2338: }
1.174 albertel 2339: my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
1.89 www 2340: .&mt('seconds');
1.174 albertel 2341: if ($env{'form.timerange'}==-1) {
1.89 www 2342: $seltext='since start of course';
2343: $startsel='selected';
1.174 albertel 2344: $env{'form.timerange'}=time;
1.89 www 2345: }
1.174 albertel 2346: $starttime=time-$env{'form.timerange'};
2347: if ($env{'form.timerange'}==2592000) {
1.89 www 2348: $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
2349: $monthsel='selected';
1.174 albertel 2350: } elsif ($env{'form.timerange'}==604800) {
1.89 www 2351: $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
2352: $weeksel='selected';
1.174 albertel 2353: } elsif ($env{'form.timerange'}==86400) {
1.89 www 2354: $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
2355: $daysel='selected';
2356: }
2357: $header=&mt('Content changed').' '.$seltext;
2358: } else {
2359: $header=&mt('No content modifications yet.');
2360: }
2361: }
1.92 www 2362: %setversions=&Apache::lonnet::dump('resourceversions',
1.174 albertel 2363: $env{'course.'.$env{'request.course.id'}.'.domain'},
2364: $env{'course.'.$env{'request.course.id'}.'.num'});
1.89 www 2365: my %lt=&Apache::lonlocal::texthash
1.325.2.6 raeburn 2366: ('st' => 'Version changes since start of '.$crstype,
1.88 www 2367: 'lm' => 'Version changes since last Month',
2368: 'lw' => 'Version changes since last Week',
2369: 'sy' => 'Version changes since Yesterday',
1.91 www 2370: 'al' => 'All Resources (possibly large output)',
1.88 www 2371: 'sd' => 'Display',
1.84 www 2372: 'fi' => 'File',
2373: 'md' => 'Modification Date',
1.87 www 2374: 'mr' => 'Most recently published Version',
1.325.2.6 raeburn 2375: 've' => 'Version used in '.$crstype,
2376: 'vu' => 'Set Version to be used in '.$crstype,
2377: 'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below',
1.91 www 2378: 'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
2379: 'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
1.84 www 2380: 'di' => 'Differences');
1.89 www 2381: $r->print(<<ENDHEADERS);
1.31 www 2382: <form action="/adm/coursedocs" method="post">
1.91 www 2383: <input type="hidden" name="versions" value="1" />
2384: <input type="submit" name="setmostrecent" value="$lt{'sm'}" />
2385: <input type="submit" name="setcurrent" value="$lt{'sc'}" /><hr />
1.31 www 2386: <select name="timerange">
1.88 www 2387: <option value='all' $allsel>$lt{'al'}</option>
1.84 www 2388: <option value="-1" $startsel>$lt{'st'}</option>
2389: <option value="2592000" $monthsel>$lt{'lm'}</option>
2390: <option value="604800" $weeksel>$lt{'lw'}</option>
2391: <option value="86400" $daysel>$lt{'sy'}</option>
1.31 www 2392: </select>
1.91 www 2393: <input type="submit" name="display" value="$lt{'sd'}" />
1.89 www 2394: <h3>$header</h3>
1.91 www 2395: <input type="submit" name="setversions" value="$lt{'sv'}" />
1.103 matthew 2396: <table border="0">
1.31 www 2397: ENDHEADERS
1.320 raeburn 2398: foreach my $key (sort(keys(%changes))) {
2399: if ($changes{$key}>$starttime) {
2400: my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
2401: my $currentversion=&Apache::lonnet::getversion($key);
1.93 www 2402: if ($currentversion<0) {
2403: $currentversion=&mt('Could not be determined.');
2404: }
1.320 raeburn 2405: my $linkurl=&Apache::lonnet::clutter($key);
1.89 www 2406: $r->print(
1.103 matthew 2407: '<tr><td colspan="5"><br /><br /><font size="+1"><b>'.
1.91 www 2408: &Apache::lonnet::gettitle($linkurl).
1.103 matthew 2409: '</b></font></td></tr>'.
2410: '<tr><td> </td>'.
2411: '<td colspan="4">'.
2412: '<a href="'.$linkurl.'" target="cat">'.$linkurl.
2413: '</a></td></tr>'.
2414: '<tr><td></td>'.
2415: '<td title="'.$lt{'md'}.'">'.
1.102 matthew 2416: &Apache::lonlocal::locallocaltime(
2417: &Apache::lonnet::metadata($root.'.'.$extension,
2418: 'lastrevisiondate')
2419: ).
1.103 matthew 2420: '</td>'.
1.284 albertel 2421: '<td title="'.$lt{'mr'}.'"><span class="LC_nobreak">Most Recent: '.
1.103 matthew 2422: '<font size="+1">'.$currentversion.'</font>'.
1.284 albertel 2423: '</span></td>'.
1.325.2.6 raeburn 2424: '<td title="'.$lt{'ve'}.'"><span class="LC_nobreak">In '.$crstype.': '.
1.103 matthew 2425: '<font size="+1">');
1.87 www 2426: # Used in course
1.89 www 2427: my $usedversion=$hash{'version_'.$linkurl};
1.93 www 2428: if (($usedversion) && ($usedversion ne 'mostrecent')) {
1.89 www 2429: $r->print($usedversion);
2430: } else {
2431: $r->print($currentversion);
2432: }
1.284 albertel 2433: $r->print('</font></span></td><td title="'.$lt{'vu'}.'">'.
2434: '<span class="LC_nobreak">Use: ');
1.87 www 2435: # Set version
1.92 www 2436: $r->print(&Apache::loncommon::select_form($setversions{$linkurl},
1.89 www 2437: 'set_version_'.$linkurl,
1.136 albertel 2438: ('select_form_order' =>
2439: ['',1..$currentversion,'mostrecent'],
2440: '' => '',
1.325.2.6 raeburn 2441: 'mostrecent' => &mt('most recent'),
1.89 www 2442: map {$_,$_} (1..$currentversion))));
1.284 albertel 2443: $r->print('</span></td></tr><tr><td></td>');
1.89 www 2444: my $lastold=1;
2445: for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
2446: my $url=$root.'.'.$prevvers.'.'.$extension;
2447: if (&Apache::lonnet::metadata($url,'lastrevisiondate')<
2448: $starttime) {
2449: $lastold=$prevvers;
2450: }
2451: }
1.103 matthew 2452: #
2453: # Code to figure out how many version entries should go in
2454: # each of the four columns
2455: my $entries_per_col = 0;
2456: my $num_entries = ($currentversion-$lastold);
2457: if ($num_entries % 4 == 0) {
2458: $entries_per_col = $num_entries/4;
2459: } else {
2460: $entries_per_col = $num_entries/4 + 1;
2461: }
2462: my $entries_count = 0;
2463: $r->print('<td valign="top"><font size="-2">');
2464: my $cols_output = 1;
1.32 www 2465: for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
1.89 www 2466: my $url=$root.'.'.$prevvers.'.'.$extension;
1.284 albertel 2467: $r->print('<span class="LC_nobreak"><a href="'.&Apache::lonnet::clutter($url).
1.91 www 2468: '">'.&mt('Version').' '.$prevvers.'</a> ('.
1.103 matthew 2469: &Apache::lonlocal::locallocaltime(
2470: &Apache::lonnet::metadata($url,
2471: 'lastrevisiondate')
2472: ).
1.91 www 2473: ')');
1.89 www 2474: if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') {
1.33 www 2475: $r->print(' <a href="/adm/diff?filename='.
1.89 www 2476: &Apache::lonnet::clutter($root.'.'.$extension).
2477: '&versionone='.$prevvers.
2478: '">'.&mt('Diffs').'</a>');
2479: }
1.284 albertel 2480: $r->print('</span><br />');
1.103 matthew 2481: if (++$entries_count % $entries_per_col == 0) {
2482: $r->print('</font></td>');
2483: if ($cols_output != 4) {
2484: $r->print('<td valign="top"><font size="-2">');
2485: $cols_output++;
2486: }
2487: }
1.89 www 2488: }
1.103 matthew 2489: while($cols_output++ < 4) {
2490: $r->print('</font></td><td><font>')
2491: }
2492: $r->print('</font></td></tr>'."\n");
1.89 www 2493: }
2494: }
1.92 www 2495: $r->print('</table></form>');
1.89 www 2496: $r->print('<h1>'.&mt('Done').'.</h1>');
2497:
2498: &untiehash();
1.75 www 2499: }
2500:
1.136 albertel 2501: sub mark_hash_old {
2502: my $retie_hash=0;
2503: if ($hashtied) {
2504: $retie_hash=1;
2505: &untiehash();
2506: }
2507: &tiehash('write');
2508: $hash{'old'}=1;
2509: &untiehash();
2510: if ($retie_hash) { &tiehash(); }
2511: }
2512:
2513: sub is_hash_old {
2514: my $untie_hash=0;
2515: if (!$hashtied) {
2516: $untie_hash=1;
2517: &tiehash();
2518: }
2519: my $return=$hash{'old'};
2520: if ($untie_hash) { &untiehash(); }
2521: return $return;
2522: }
2523:
1.91 www 2524: sub changewarning {
1.177 albertel 2525: my ($r,$postexec,$message,$url)=@_;
1.136 albertel 2526: if (!&is_hash_old()) { return; }
1.150 albertel 2527: my $pathvar='folderpath';
1.228 www 2528: my $path=&escape($env{'form.folderpath'});
1.177 albertel 2529: if (!defined($url)) {
2530: if (defined($env{'form.pagepath'})) {
2531: $pathvar='pagepath';
1.228 www 2532: $path=&escape($env{'form.pagepath'});
2533: $path.='&pagesymb='.&escape($env{'form.pagesymb'});
1.177 albertel 2534: }
2535: $url='/adm/coursedocs?'.$pathvar.'='.$path;
2536: }
1.230 albertel 2537: my $course_type = &Apache::loncommon::course_type();
1.177 albertel 2538: if (!defined($message)) {
2539: $message='Changes will become active for your current session after [_1], or the next time you log in.';
1.150 albertel 2540: }
1.185 www 2541: $r->print("\n\n".
1.325.2.3 raeburn 2542: '<script type="text/javascript">'."\n".
2543: '// <![CDATA['."\n".
2544: 'function reinit(tf) { tf.submit();'.$postexec.' }'."\n".
2545: '// ]]>'."\n".
1.325.2.2 raeburn 2546: '</script>'."\n".
1.185 www 2547: '<form name="reinitform" method="post" action="/adm/roles" target="loncapaclient">'.
1.177 albertel 2548: '<input type="hidden" name="orgurl" value="'.$url.
1.325.2.3 raeburn 2549: '" /><input type="hidden" name="selectrole" value="1" /><p class="LC_warning">'.
1.177 albertel 2550: &mt($message,' <input type="hidden" name="'.
2551: $env{'request.role'}.'" value="1" /><input type="button" value="'.
1.325.2.2 raeburn 2552: &mt('re-initializing '.$course_type).'" onclick="reinit(this.form)" />').
1.325.2.3 raeburn 2553: $help{'Caching'}.'</p></form>'."\n\n");
2554:
1.91 www 2555: }
2556:
1.257 www 2557:
2558: sub init_breadcrumbs {
2559: my ($form,$text)=@_;
2560: &Apache::lonhtmlcommon::clear_breadcrumbs();
2561: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs",
1.325.2.5 raeburn 2562: text=>&Apache::loncommon::course_type().' Editor',
1.257 www 2563: faq=>273,
2564: bug=>'Instructor Interface',
2565: help => 'Docs_Adding_Course_Doc'});
2566: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
2567: text=>$text,
2568: faq=>273,
2569: bug=>'Instructor Interface'});
2570: }
2571:
1.315 jms 2572:
2573:
2574:
1.75 www 2575: sub handler {
2576: my $r = shift;
1.82 www 2577: &Apache::loncommon::content_type($r,'text/html');
1.75 www 2578: $r->send_http_header;
2579: return OK if $r->header_only;
1.325.2.6 raeburn 2580: my $crstype = &Apache::loncommon::course_type();
1.75 www 2581:
2582: # --------------------------------------------- Initialize help topics for this
1.320 raeburn 2583: foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
2584: 'Adding_External_Resource','Navigate_Content',
2585: 'Adding_Folders','Docs_Overview', 'Load_Map',
2586: 'Supplemental','Score_Upload_Form','Adding_Pages',
2587: 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
2588: 'Check_Resource_Versions','Verify_Content') {
2589: $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
1.209 albertel 2590: }
1.75 www 2591: # Composite help files
2592: $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
2593: 'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
2594: $help{'Simple Page'} = &Apache::loncommon::help_open_topic(
2595: 'Docs_About_Simple_Page,Docs_Editing_Templated_Pages');
1.86 albertel 2596: $help{'Simple Problem'} = &Apache::loncommon::help_open_topic(
2597: 'Option_Response_Simple');
1.75 www 2598: $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
2599: 'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
2600: $help{'My Personal Info'} = &Apache::loncommon::help_open_topic(
2601: 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
1.255 raeburn 2602: $help{'Group Files'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
1.75 www 2603: $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
1.142 raeburn 2604:
1.209 albertel 2605: # does this user have privileges to modify docs
2606: my $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'});
2607: if ($allowed && $env{'form.verify'}) {
1.257 www 2608: &init_breadcrumbs('verify','Verify Content');
1.75 www 2609: &verifycontent($r);
1.209 albertel 2610: } elsif ($allowed && $env{'form.listsymbs'}) {
1.257 www 2611: &init_breadcrumbs('listsymbs','List Symbs');
1.208 albertel 2612: &list_symbs($r);
1.247 www 2613: } elsif ($allowed && $env{'form.docslog'}) {
1.257 www 2614: &init_breadcrumbs('docslog','Show Log');
1.247 www 2615: &docs_change_log($r);
1.209 albertel 2616: } elsif ($allowed && $env{'form.versions'}) {
1.257 www 2617: &init_breadcrumbs('versions','Check/Set Resource Versions');
1.75 www 2618: &checkversions($r);
1.209 albertel 2619: } elsif ($allowed && $env{'form.dumpcourse'}) {
1.257 www 2620: &init_breadcrumbs('dumpcourse','Dump '.&Apache::loncommon::course_type().' DOCS to Construction Space');
1.75 www 2621: &dumpcourse($r);
1.209 albertel 2622: } elsif ($allowed && $env{'form.exportcourse'}) {
1.325.2.4 raeburn 2623: &init_breadcrumbs('exportcourse','IMS Export');
1.138 raeburn 2624: &exportcourse($r);
1.26 www 2625: } else {
1.7 www 2626: # is this a standard course?
2627:
1.174 albertel 2628: my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
1.155 raeburn 2629: my $forcestandard = 0;
1.15 www 2630: my $forcesupplement;
2631: my $script='';
1.19 www 2632: my $showdoc=0;
1.142 raeburn 2633: my $containertag;
2634: my $uploadtag;
1.15 www 2635: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.224 albertel 2636: ['folderpath','pagepath',
1.281 albertel 2637: 'pagesymb']);
1.307 www 2638: # No folderpath, no pagepath, see if we have something stored
2639: if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'})) {
2640: &Apache::loncommon::restore_course_settings('docs_folderpath',
2641: {'folderpath' => 'scalar'});
2642: }
2643: if (!$env{'form.folderpath'}) {
2644: &Apache::loncommon::restore_course_settings('docs_folderpath',
2645: {'pagepath' => 'scalar'});
2646: }
2647: if ($env{'form.pagepath'}) {
2648: $env{'form.folderpath'}='';
2649: }
1.309 raeburn 2650: if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
2651: $env{'form.folderpath'} = 'supplemental&'.
1.325.2.6 raeburn 2652: &escape(&mt('Supplemental '.$crstype.' Documents')).'&'.
1.309 raeburn 2653: $env{'form.folderpath'};
2654: }
1.307 www 2655: &Apache::loncommon::store_course_settings('docs_folderpath',
2656: {'pagepath' => 'scalar',
2657: 'folderpath' => 'scalar'});
1.174 albertel 2658: if ($env{'form.folderpath'}) {
2659: my (@folderpath)=split('&',$env{'form.folderpath'});
1.228 www 2660: $env{'form.foldername'}=&unescape(pop(@folderpath));
1.174 albertel 2661: $env{'form.folder'}=pop(@folderpath);
2662: }
2663: if ($env{'form.pagepath'}) {
2664: my (@pagepath)=split('&',$env{'form.pagepath'});
1.228 www 2665: $env{'form.pagename'}=&unescape(pop(@pagepath));
1.174 albertel 2666: $env{'form.folder'}=pop(@pagepath);
1.156 albertel 2667: $containertag = '<input type="hidden" name="pagepath" value="" />'.
2668: '<input type="hidden" name="pagesymb" value="" />';
1.282 albertel 2669: $uploadtag = '<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($env{'form.pagepath'},'<>&"').'" />'.
2670: '<input type="hidden" name="pagesymb" value="'.&HTML::Entities::encode($env{'form.pagesymb'},'<>&"').'" />';
1.142 raeburn 2671: }
1.21 www 2672: if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
1.127 albertel 2673: $showdoc='/'.$1;
1.21 www 2674: }
2675: unless ($showdoc) { # got called from remote
1.237 albertel 2676: if (($env{'form.folder'}=~/^(?:group|default)_/) ||
1.209 albertel 2677: ($env{'form.folder'} =~ m:^\d+/(pages|sequences)/:)) {
1.155 raeburn 2678: $forcestandard = 1;
2679: }
1.174 albertel 2680: $forcesupplement=($env{'form.folder'}=~/^supplemental_/);
1.7 www 2681:
1.15 www 2682: if ($allowed) {
2683: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
2684: $script=&Apache::lonratedt::editscript('simple');
2685: }
2686: } else { # got called in sequence from course
2687: $allowed=0;
1.3 www 2688: }
1.4 www 2689:
2690: # get course data
1.174 albertel 2691: my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
2692: my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.4 www 2693:
1.225 albertel 2694: # get personal data
1.174 albertel 2695: my $uname=$env{'user.name'};
2696: my $udom=$env{'user.domain'};
1.245 albertel 2697: my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom));
1.14 www 2698:
1.8 www 2699: # graphics settings
1.4 www 2700:
1.176 albertel 2701: $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/");
1.8 www 2702:
1.224 albertel 2703: if ($allowed) {
2704: $script .= &editing_js($udom,$uname);
1.171 www 2705: }
1.42 www 2706: # -------------------------------------------------------------------- Body tag
1.325.2.2 raeburn 2707: $script = '<script type="text/javascript">'."\n"
1.325.2.3 raeburn 2708: .'// <![CDATA['."\n"
2709: .$script."\n"
2710: .'// ]]>'."\n"
2711: .'</script>'."\n";
1.325.2.9! raeburn 2712: my $brcrum = [{href=>"/adm/createuser",text=>"Edit $crstype"}];
! 2713: $r->print(&Apache::loncommon::start_page("Edit $crstype", $script,
1.324 raeburn 2714: {'force_register' => $showdoc,
2715: 'bread_crumbs' => $brcrum}).
1.233 albertel 2716: &Apache::loncommon::help_open_menu('','',273,'RAT'));
1.224 albertel 2717:
1.188 raeburn 2718: my %allfiles = ();
2719: my %codebase = ();
2720: my ($upload_result,$upload_output);
2721: if ($allowed) {
1.264 albertel 2722: if (($env{'form.uploaddoc.filename'}) &&
2723: ($env{'form.cmd'}=~/^upload_(\w+)/)) {
1.188 raeburn 2724: # Process file upload - phase one - upload and parse primary file.
1.298 albertel 2725: undef($hadchanges);
1.190 albertel 2726: $upload_result = &process_file_upload(\$upload_output,$coursenum,
2727: $coursedom,\%allfiles,
1.194 raeburn 2728: \%codebase,$1);
1.298 albertel 2729: if ($hadchanges) {
2730: &mark_hash_old();
2731: }
1.188 raeburn 2732: if ($upload_result eq 'phasetwo') {
2733: $r->print($upload_output);
2734: }
2735: } elsif ($env{'form.phasetwo'}) {
2736: my %newname = ();
2737: my %origname = ();
2738: my %attribs = ();
2739: my $updateflag = 0;
2740: my $residx = $env{'form.newidx'};
1.228 www 2741: my $primary_url = &unescape($env{'form.primaryurl'});
1.188 raeburn 2742: # Process file upload - phase two - gather secondary files.
2743: for (my $i=0; $i<$env{'form.phasetwo'}; $i++) {
2744: if ($env{'form.embedded_item_'.$i.'.filename'}) {
2745: my $javacodebase;
2746: $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx);
1.228 www 2747: $origname{$i} = &unescape($env{'form.embedded_orig_'.$i});
1.188 raeburn 2748: if (exists($env{'form.embedded_codebase_'.$i})) {
1.228 www 2749: $javacodebase = &unescape($env{'form.embedded_codebase_'.$i});
1.188 raeburn 2750: $origname{$i} =~ s#^\Q$javacodebase\E/##;
2751: }
2752: my @attributes = ();
2753: if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
1.320 raeburn 2754: @attributes = split(/:/,$env{'form.embedded_attrib_'.$i});
1.188 raeburn 2755: } else {
2756: @attributes = ($env{'form.embedded_attrib_'.$i});
2757: }
1.320 raeburn 2758: foreach my $attr (@attributes) {
2759: push(@{$attribs{$i}},&unescape($attr));
1.188 raeburn 2760: }
2761: if ($javacodebase) {
2762: $codebase{$i} = $javacodebase;
2763: $codebase{$i} =~ s#/$##;
2764: $updateflag = 1;
2765: }
2766: }
2767: unless ($newname{$i} eq $origname{$i}) {
2768: $updateflag = 1;
2769: }
2770: }
2771: # Process file upload - phase three - modify primary file
2772: if ($updateflag) {
2773: my ($content,$rtncode);
2774: my $updateflag = 0;
2775: my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
2776: if ($getstatus eq 'ok') {
1.320 raeburn 2777: foreach my $item (keys(%newname)) {
1.188 raeburn 2778: if ($newname{$item} ne $origname{$item}) {
2779: my $attrib_regexp = '';
2780: if (@{$attribs{$item}} > 1) {
2781: $attrib_regexp = join('|',@{$attribs{$item}});
2782: } else {
2783: $attrib_regexp = $attribs{$item}[0];
2784: }
2785: if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) {
2786: }
2787: $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi;
2788: }
2789: if (exists($codebase{$item})) {
1.224 albertel 2790: $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; #' stupid emacs
1.188 raeburn 2791: }
2792: }
2793: # Save edited file.
2794: my $saveresult;
2795: my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
2796: my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.191 raeburn 2797: my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,\$saveresult);
1.188 raeburn 2798: } else {
2799: &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus);
2800: }
2801: }
2802: }
2803: }
2804:
2805: unless ($showdoc || $upload_result eq 'phasetwo') {
1.81 www 2806: # -----------------------------------------------------------------------------
2807: my %lt=&Apache::lonlocal::texthash(
1.325.2.6 raeburn 2808: 'uplm' => 'Upload a new main '.lc($crstype).' document',
2809: 'upls' => 'Upload a new supplemental '.lc($crstype).' document',
1.168 www 2810: 'impp' => 'Import a document',
2811: 'pubd' => 'Published documents',
1.181 www 2812: 'copm' => 'All documents out of a published map into this folder',
1.81 www 2813: 'spec' => 'Special documents',
2814: 'upld' => 'Upload Document',
2815: 'srch' => 'Search',
2816: 'impo' => 'Import',
1.232 www 2817: 'book' => 'Import Bookmarks',
1.81 www 2818: 'selm' => 'Select Map',
2819: 'load' => 'Load Map',
1.186 www 2820: 'reco' => 'Recover Deleted Resources',
1.81 www 2821: 'newf' => 'New Folder',
1.142 raeburn 2822: 'newp' => 'New Composite Page',
1.81 www 2823: 'extr' => 'External Resource',
2824: 'syll' => 'Syllabus',
2825: 'navc' => 'Navigate Contents',
1.325.2.1 raeburn 2826: 'sipa' => 'Simple Course Page',
1.81 www 2827: 'sipr' => 'Simple Problem',
1.219 www 2828: 'drbx' => 'Drop Box',
1.81 www 2829: 'scuf' => 'Score Upload Form',
1.325.2.1 raeburn 2830: 'bull' => 'Discussion Board',
2831: 'mypi' => 'My Personal Information Page',
2832: 'grpo' => 'Group Portfolios',
1.294 raeburn 2833: 'rost' => 'Course Roster',
1.101 www 2834: 'abou' => 'About User',
1.325.2.4 raeburn 2835: 'imsf' => 'IMS Import',
2836: 'imsl' => 'Import IMS package',
1.96 sakharuk 2837: 'file' => 'File',
2838: 'title' => 'Title',
1.188 raeburn 2839: 'comment' => 'Comment',
2840: 'parse' => 'If HTML file, upload embedded images/multimedia files'
1.81 www 2841: );
2842: # -----------------------------------------------------------------------------
1.325.2.5 raeburn 2843: my %tabtitles = (
2844: main => {
2845: Course => &mt('Main Course Documents'),
2846: Community => &mt('Main Community Documents'),
2847: },
2848: supplemental => {
2849: Course => &mt('Supplemental Course Documents'),
2850: Community => &mt('Supplemental Community Documents'),
2851: },
2852: );
1.42 www 2853: if ($allowed) {
1.281 albertel 2854: &update_paste_buffer($coursenum,$coursedom);
1.74 www 2855: my $dumpbut=&dumpbutton();
1.138 raeburn 2856: my $exportbut=&exportbutton();
1.88 www 2857: my %lt=&Apache::lonlocal::texthash(
2858: 'vc' => 'Verify Content',
2859: 'cv' => 'Check/Set Resource Versions',
1.208 albertel 2860: 'ls' => 'List Symbs',
1.247 www 2861: 'sl' => 'Show Log'
1.88 www 2862: );
1.118 albertel 2863:
1.174 albertel 2864: my $folderpath=$env{'form.folderpath'};
1.118 albertel 2865: if (!$folderpath) {
1.174 albertel 2866: if ($env{'form.folder'} eq '' ||
2867: $env{'form.folder'} eq 'supplemental') {
1.325.2.6 raeburn 2868: $folderpath='default&'.&escape($tabtitles{'main'}{$crstype});
1.118 albertel 2869: }
2870: }
1.174 albertel 2871: unless ($env{'form.pagepath'}) {
1.142 raeburn 2872: $containertag = '<input type="hidden" name="folderpath" value="" />';
1.282 albertel 2873: $uploadtag = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />';
1.142 raeburn 2874: }
2875:
1.42 www 2876: $r->print(<<ENDCOURSEVERIFY);
1.36 www 2877: <form name="renameform" method="post" action="/adm/coursedocs">
1.283 albertel 2878: <input type="hidden" name="title" />
2879: <input type="hidden" name="cmd" />
2880: <input type="hidden" name="markcopy" />
2881: <input type="hidden" name="copyfolder" />
2882: $containertag
1.36 www 2883: </form>
1.39 www 2884: <form name="simpleedit" method="post" action="/adm/coursedocs">
1.283 albertel 2885: <input type="hidden" name="importdetail" value="" />
2886: $uploadtag
1.39 www 2887: </form>
1.26 www 2888: <form action="/adm/coursedocs" method="post" name="courseverify">
1.283 albertel 2889: <div class="LC_docs_course_commands">
2890:
2891: <div>
2892: <input type="submit" name="verify" value="$lt{'vc'}" />$help{'Verify_Content'}
2893: </div>
2894: <div>
2895: <input type="submit" name="versions" value="$lt{'cv'}" />$help{'Check_Resource_Versions'}
2896: </div>
2897: $dumpbut
2898: $exportbut
2899: <div>
2900: <input type="submit" name="listsymbs" value="$lt{'ls'}" />
2901: </div>
2902: <div>
2903: <input type="hidden" name="folder" value="$env{'form.folder'}" />
2904: <input type="submit" name="docslog" value="$lt{'sl'}" />
2905: </div>
2906: </div>
1.25 www 2907: </form>
1.283 albertel 2908: <div style="clear: both; height: 0px;"> </div>
1.25 www 2909: ENDCOURSEVERIFY
1.74 www 2910: $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc',
1.325.2.6 raeburn 2911: &mt('Editing the Table of Contents for your '.$crstype)));
1.25 www 2912: }
1.17 www 2913: # --------------------------------------------------------- Standard documents
1.293 albertel 2914: $r->print('<table class="LC_docs_documents">');
2915:
1.7 www 2916: if (($standard) && ($allowed) && (!$forcesupplement)) {
1.285 albertel 2917: $r->print('<tr><td class="LC_docs_document">');
1.116 albertel 2918: # '<h2>'.&mt('Main Course Documents').
2919: # ($allowed?' '.$help{'Main_Course_Documents'}:'').'</h2>');
1.174 albertel 2920: my $folder=$env{'form.folder'};
1.117 albertel 2921: if ($folder eq '' || $folder eq 'supplemental') {
1.112 raeburn 2922: $folder='default';
1.325.2.6 raeburn 2923: $env{'form.folderpath'}='default&'.&escape(&mt('Main '.$crstype.' Documents'));
1.293 albertel 2924: $uploadtag = '<input type="hidden" name="folderpath" value="'.
2925: &HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />';
1.112 raeburn 2926: }
1.51 www 2927: my $postexec='';
2928: if ($folder eq 'default') {
1.325.2.3 raeburn 2929: $r->print('<script type="text/javascript">'."\n"
2930: .'// <![CDATA['."\n"
2931: .'this.window.name="loncapaclient";'."\n"
2932: .'// ]]>'."\n"
2933: .'</script>'."\n"
1.325.2.2 raeburn 2934: );
1.51 www 2935: } else {
1.117 albertel 2936: #$postexec='self.close();';
1.51 www 2937: }
1.40 www 2938: $hadchanges=0;
1.292 albertel 2939: my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,
1.325.2.6 raeburn 2940: $upload_output,$crstype);
1.292 albertel 2941: if ($error) {
2942: $r->print('<p><span class="LC_error">'.$error.'</span></p>');
2943: }
1.40 www 2944: if ($hadchanges) {
1.320 raeburn 2945: &mark_hash_old();
1.40 www 2946: }
1.136 albertel 2947: &changewarning($r,$postexec);
1.16 www 2948: my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
2949: '.sequence';
1.142 raeburn 2950: my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
2951: '.page';
1.186 www 2952: my $container='sequence';
2953: if ($env{'form.pagepath'}) {
2954: $container='page';
2955: }
2956: my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container;
1.8 www 2957: $r->print(<<ENDFORM);
1.285 albertel 2958: <table class="LC_docs_adddocs">
2959: <tr>
2960: <th>$lt{'uplm'}</th>
2961: <th>$lt{'impp'}</th>
2962: <th>$lt{'spec'}</th>
1.11 www 2963: </tr>
1.285 albertel 2964: <tr>
2965: <td>
1.96 sakharuk 2966: $lt{'file'}:<br />
1.182 albertel 2967: <form name="uploaddocument" action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286 albertel 2968: <input type="file" name="uploaddoc" size="40" />
1.8 www 2969: <br />
1.96 sakharuk 2970: $lt{'title'}:<br />
1.286 albertel 2971: <input type="text" size="50" name="comment" />
1.142 raeburn 2972: $uploadtag
1.286 albertel 2973: <input type="hidden" name="cmd" value="upload_default" />
1.188 raeburn 2974: <br />
1.284 albertel 2975: <span class="LC_nobreak">
1.190 albertel 2976: <label>$lt{'parse'}?
1.306 www 2977: <input type="checkbox" name="parserflag" checked="checked" />
1.190 albertel 2978: </label>
1.284 albertel 2979: </span>
1.188 raeburn 2980: <br />
2981: <br />
1.284 albertel 2982: <span class="LC_nobreak">
1.286 albertel 2983: <input type="submit" value="$lt{'upld'}" />
1.60 albertel 2984: $help{'Uploading_From_Harddrive'}
1.284 albertel 2985: </span>
1.60 albertel 2986: </form>
1.11 www 2987: </td>
1.285 albertel 2988: <td>
1.39 www 2989: <form action="/adm/coursedocs" method="post" name="simpleeditdefault">
1.168 www 2990: $lt{'pubd'}<br />
1.142 raeburn 2991: $uploadtag
1.325.2.2 raeburn 2992: <input type="button" onclick="javascript:groupsearch()" value="$lt{'srch'}" />
1.232 www 2993: <br />
1.284 albertel 2994: <span class="LC_nobreak">
1.325.2.2 raeburn 2995: <input type="button" onclick="javascript:groupimport();" value="$lt{'impo'}" />
1.58 albertel 2996: $help{'Importing_LON-CAPA_Resource'}
1.284 albertel 2997: </span>
1.232 www 2998: <br />
1.325.2.2 raeburn 2999: <input type="button" onclick="javascript:groupopen(0,1,1);" value="$lt{'book'}" />
1.286 albertel 3000: <hr />
1.59 www 3001: <p>
1.181 www 3002: $lt{'copm'}<br />
1.282 albertel 3003: <input type="text" size="40" name="importmap" /><br />
1.286 albertel 3004: <span class="LC_nobreak"><input type="button"
1.325.2.2 raeburn 3005: onclick="javascript:openbrowser('simpleeditdefault','importmap','sequence,page','')"
1.282 albertel 3006: value="$lt{'selm'}" /> <input type="submit" name="loadmap" value="$lt{'load'}" />
1.284 albertel 3007: $help{'Load_Map'}</span>
1.59 www 3008: </p>
1.52 www 3009: </form>
1.186 www 3010: <hr />
3011: <form action="/adm/groupsort" method="post" name="recover">
1.325.2.2 raeburn 3012: <input type="button" name="recovermap" onclick="javascript:groupopen('$readfile',1,0)" value="$lt{'reco'}" />
1.186 www 3013: </form>
1.142 raeburn 3014: ENDFORM
1.174 albertel 3015: unless ($env{'form.pagepath'}) {
1.168 www 3016: $r->print(<<ENDFORM);
3017: <hr />
3018: <form action="/adm/coursedocs" method="post" name="newext">
3019: $uploadtag
1.256 albertel 3020: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3021: <span class="LC_nobreak">
1.325.2.2 raeburn 3022: <input name="newext" type="button" onclick="javascript:makenewext('newext');"
1.168 www 3023: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284 albertel 3024: </span>
1.168 www 3025: </form>
1.214 www 3026: <br /><form action="/adm/imsimportdocs" method="post" name="ims">
1.168 www 3027: <input type="hidden" name="folder" value="$folder" />
1.325.2.4 raeburn 3028: <input name="imsimport" type="button" value="$lt{'imsf'}" title="$lt{imsl}" onclick="javascript:makeims();" />
1.168 www 3029: </form>
3030: ENDFORM
3031: }
1.285 albertel 3032: $r->print('</td><td>');
1.174 albertel 3033: unless ($env{'form.pagepath'}) {
1.282 albertel 3034: my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
1.142 raeburn 3035: $r->print(<<ENDFORM);
1.214 www 3036: <br /><form action="/adm/coursedocs" method="post" name="newfolder">
1.282 albertel 3037: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3038: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3039: <span class="LC_nobreak">
1.16 www 3040: <input name="newfolder" type="button"
1.325.2.2 raeburn 3041: onclick="javascript:makenewfolder(this.form,'$folderseq');"
1.81 www 3042: value="$lt{'newf'}" />$help{'Adding_Folders'}
1.284 albertel 3043: </span>
1.11 www 3044: </form>
1.214 www 3045: <br /><form action="/adm/coursedocs" method="post" name="newpage">
1.282 albertel 3046: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3047: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3048: <span class="LC_nobreak">
1.142 raeburn 3049: <input name="newpage" type="button"
1.325.2.2 raeburn 3050: onclick="javascript:makenewpage(this.form,'$pageseq');"
1.142 raeburn 3051: value="$lt{'newp'}" />$help{'Adding_Pages'}
1.284 albertel 3052: </span>
1.142 raeburn 3053: </form>
1.214 www 3054: <br /><form action="/adm/coursedocs" method="post" name="newsyl">
1.142 raeburn 3055: $uploadtag
1.256 albertel 3056: <input type="hidden" name="importdetail"
1.305 bisitz 3057: value="$lt{'syll'}=/public/$coursedom/$coursenum/syllabus" />
1.284 albertel 3058: <span class="LC_nobreak">
1.81 www 3059: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65 bowersj2 3060: $help{'Syllabus'}
1.284 albertel 3061: </span>
1.58 albertel 3062: </form>
1.214 www 3063: <br /><form action="/adm/coursedocs" method="post" name="newnav">
1.142 raeburn 3064: $uploadtag
1.256 albertel 3065: <input type="hidden" name="importdetail"
1.305 bisitz 3066: value="$lt{'navc'}=/adm/navmaps" />
1.284 albertel 3067: <span class="LC_nobreak">
1.81 www 3068: <input name="newnav" type="submit" value="$lt{'navc'}" />
1.47 www 3069: $help{'Navigate_Content'}
1.284 albertel 3070: </span>
1.22 www 3071: </form>
1.214 www 3072: <br /><form action="/adm/coursedocs" method="post" name="newsmppg">
1.142 raeburn 3073: $uploadtag
1.256 albertel 3074: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3075: <span class="LC_nobreak">
1.81 www 3076: <input name="newsmppg" type="button" value="$lt{'sipa'}"
1.325.2.2 raeburn 3077: onclick="javascript:makesmppage();" /> $help{'Simple Page'}
1.284 albertel 3078: </span>
1.55 www 3079: </form>
1.214 www 3080: <br /><form action="/adm/coursedocs" method="post" name="newsmpproblem">
1.142 raeburn 3081: $uploadtag
1.256 albertel 3082: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3083: <span class="LC_nobreak">
1.81 www 3084: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
1.325.2.2 raeburn 3085: onclick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284 albertel 3086: </span>
1.62 www 3087: </form>
1.219 www 3088: <br /><form action="/adm/coursedocs" method="post" name="newdropbox">
3089: $uploadtag
1.256 albertel 3090: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3091: <span class="LC_nobreak">
1.219 www 3092: <input name="newdropbox" type="button" value="$lt{'drbx'}"
1.325.2.2 raeburn 3093: onclick="javascript:makedropbox();" />
1.284 albertel 3094: </span>
1.219 www 3095: </form>
1.214 www 3096: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142 raeburn 3097: $uploadtag
1.256 albertel 3098: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3099: <span class="LC_nobreak">
1.81 www 3100: <input name="newexamupload" type="button" value="$lt{'scuf'}"
1.325.2.2 raeburn 3101: onclick="javascript:makeexamupload();" />
1.66 bowersj2 3102: $help{'Score_Upload_Form'}
1.284 albertel 3103: </span>
1.22 www 3104: </form>
1.214 www 3105: <br /><form action="/adm/coursedocs" method="post" name="newbul">
1.142 raeburn 3106: $uploadtag
1.256 albertel 3107: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3108: <span class="LC_nobreak">
1.81 www 3109: <input name="newbulletin" type="button" value="$lt{'bull'}"
1.325.2.2 raeburn 3110: onclick="javascript:makebulboard();" />
1.65 bowersj2 3111: $help{'Bulletin Board'}
1.284 albertel 3112: </span>
1.58 albertel 3113: </form>
1.214 www 3114: <br /><form action="/adm/coursedocs" method="post" name="newaboutme">
1.142 raeburn 3115: $uploadtag
1.256 albertel 3116: <input type="hidden" name="importdetail"
3117: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284 albertel 3118: <span class="LC_nobreak">
1.81 www 3119: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65 bowersj2 3120: $help{'My Personal Info'}
1.284 albertel 3121: </span>
1.101 www 3122: </form>
1.214 www 3123: <br /><form action="/adm/coursedocs" method="post" name="newaboutsomeone">
1.142 raeburn 3124: $uploadtag
1.256 albertel 3125: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3126: <span class="LC_nobreak">
1.101 www 3127: <input name="newaboutsomeone" type="button" value="$lt{'abou'}"
1.325.2.2 raeburn 3128: onclick="javascript:makeabout();" />
1.284 albertel 3129: </span>
1.182 albertel 3130: </form>
1.255 raeburn 3131: <br /><form action="/adm/coursedocs" method="post" name="newgroupfiles">
3132: $uploadtag
1.256 albertel 3133: <input type="hidden" name="importdetail"
1.305 bisitz 3134: value="$lt{'grpo'}=/adm/$coursedom/$coursenum/aboutme" />
1.284 albertel 3135: <span class="LC_nobreak">
1.255 raeburn 3136: <input name="newgroupfiles" type="submit" value="$lt{'grpo'}" />
3137: $help{'Group Files'}
1.284 albertel 3138: </span>
1.255 raeburn 3139: </form>
1.294 raeburn 3140: <br /><form action="/adm/coursedocs" method="post" name="newroster">
3141: $uploadtag
3142: <input type="hidden" name="importdetail"
1.305 bisitz 3143: value="$lt{'rost'}=/adm/viewclasslist" />
1.294 raeburn 3144: <span class="LC_nobreak">
3145: <input name="newroster" type="submit" value="$lt{'rost'}" />
3146: $help{'Course Roster'}
3147: </span>
3148: </form>
1.142 raeburn 3149: ENDFORM
3150: }
1.174 albertel 3151: if ($env{'form.pagepath'}) {
1.142 raeburn 3152: $r->print(<<ENDBLOCK);
3153: <form action="/adm/coursedocs" method="post" name="newsmpproblem">
3154: $uploadtag
1.256 albertel 3155: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3156: <span class="LC_nobreak">
1.142 raeburn 3157: <input name="newsmpproblem" type="button" value="$lt{'sipr'}"
1.325.2.2 raeburn 3158: onclick="javascript:makesmpproblem();" />$help{'Simple Problem'}
1.284 albertel 3159: </span>
1.142 raeburn 3160: </form>
1.214 www 3161: <br /><form action="/adm/coursedocs" method="post" name="newexamupload">
1.142 raeburn 3162: $uploadtag
1.256 albertel 3163: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3164: <span class="LC_nobreak">
1.142 raeburn 3165: <input name="newexamupload" type="button" value="$lt{'scuf'}"
1.325.2.2 raeburn 3166: onclick="javascript:makeexamupload();" />
1.142 raeburn 3167: $help{'Score_Upload_Form'}
1.284 albertel 3168: </span>
1.182 albertel 3169: </form>
1.142 raeburn 3170: ENDBLOCK
3171: }
3172: $r->print('</td></tr>'."\n".
3173: '</table>');
1.24 www 3174: $r->print('</td></tr>');
1.7 www 3175: }
3176: # ----------------------------------------------------- Supplemental documents
3177: if (!$forcestandard) {
1.285 albertel 3178: $r->print('<tr><td class="LC_docs_document">');
1.116 albertel 3179: # '<h2>'.&mt('Supplemental Course Documents').
3180: # ($allowed?' '.$help{'Supplemental'}:'').'</h2>');
1.174 albertel 3181: my $folder=$env{'form.folder'};
1.117 albertel 3182: unless ($folder=~/^supplemental/) {
1.116 albertel 3183: $folder='supplemental';
1.117 albertel 3184: }
3185: if ($folder =~ /^supplemental$/ &&
1.309 raeburn 3186: (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
3187: $env{'form.folderpath'} = 'supplemental&'.
1.325.2.6 raeburn 3188: &escape($tabtitles{'supplemental'}{$crstype});
1.116 albertel 3189: }
1.325.2.6 raeburn 3190: my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype);
1.292 albertel 3191: if ($error) {
3192: $r->print('<p><span class="LC_error">'.$error.'</span></p>');
3193: }
1.8 www 3194: if ($allowed) {
1.282 albertel 3195: my $folderseq=
3196: '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_'.time.
3197: '.sequence';
1.17 www 3198:
1.282 albertel 3199: my $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
3200: $r->print(<<ENDSUPFORM);
1.285 albertel 3201: <table class="LC_docs_adddocs"><tr>
3202: <th>$lt{'upls'}</th>
3203: <th>$lt{'spec'}</th>
1.17 www 3204: </tr>
1.285 albertel 3205: <tr><td>
1.10 www 3206: <form action="/adm/coursedocs" method="post" enctype="multipart/form-data">
1.286 albertel 3207: <input type="file" name="uploaddoc" size="40" />
1.196 raeburn 3208: <br />
3209: <br />
1.284 albertel 3210: <span class="LC_nobreak">
1.196 raeburn 3211: <label>$lt{'parse'}?
3212: <input type="checkbox" name="parserflag" />
3213: </label>
1.284 albertel 3214: </span>
1.196 raeburn 3215: <br /><br />
3216: $lt{'comment'}:<br />
1.325.2.1 raeburn 3217: <textarea cols="50" rows="4" name="comment">
1.4 www 3218: </textarea>
1.115 albertel 3219: <br />
1.282 albertel 3220: <input type="hidden" name="folderpath" value="$path" />
1.286 albertel 3221: <input type="hidden" name="cmd" value="upload_supplemental" />
1.284 albertel 3222: <span class="LC_nobreak">
1.286 albertel 3223: <input type="submit" value="$lt{'upld'}" />
1.58 albertel 3224: $help{'Uploading_From_Harddrive'}
1.284 albertel 3225: </span>
1.58 albertel 3226: </form>
1.17 www 3227: </td>
1.285 albertel 3228: <td>
1.18 www 3229: <form action="/adm/coursedocs" method="post" name="supnewfolder">
1.282 albertel 3230: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3231: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3232: <span class="LC_nobreak">
1.17 www 3233: <input name="newfolder" type="button"
1.325.2.2 raeburn 3234: onclick="javascript:makenewfolder(this.form,'$folderseq');"
1.81 www 3235: value="$lt{'newf'}" /> $help{'Adding_Folders'}
1.284 albertel 3236: </span>
1.17 www 3237: </form>
1.214 www 3238: <br /><form action="/adm/coursedocs" method="post" name="supnewext">
1.282 albertel 3239: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3240: <input type="hidden" name="importdetail" value="" />
1.284 albertel 3241: <span class="LC_nobreak">
1.18 www 3242: <input name="newext" type="button"
1.325.2.2 raeburn 3243: onclick="javascript:makenewext('supnewext');"
1.81 www 3244: value="$lt{'extr'}" /> $help{'Adding_External_Resource'}
1.284 albertel 3245: </span>
1.17 www 3246: </form>
1.214 www 3247: <br /><form action="/adm/coursedocs" method="post" name="supnewsyl">
1.282 albertel 3248: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3249: <input type="hidden" name="importdetail"
3250: value="Syllabus=/public/$coursedom/$coursenum/syllabus" />
1.284 albertel 3251: <span class="LC_nobreak">
1.81 www 3252: <input name="newsyl" type="submit" value="$lt{'syll'}" />
1.65 bowersj2 3253: $help{'Syllabus'}
1.284 albertel 3254: </span>
1.58 albertel 3255: </form>
1.214 www 3256: <br /><form action="/adm/coursedocs" method="post" name="subnewaboutme">
1.282 albertel 3257: <input type="hidden" name="folderpath" value="$path" />
1.256 albertel 3258: <input type="hidden" name="importdetail"
3259: value="$plainname=/adm/$udom/$uname/aboutme" />
1.284 albertel 3260: <span class="LC_nobreak">
1.81 www 3261: <input name="newaboutme" type="submit" value="$lt{'mypi'}" />
1.65 bowersj2 3262: $help{'My Personal Info'}
1.284 albertel 3263: </span>
1.58 albertel 3264: </form>
1.17 www 3265: </td></tr>
1.24 www 3266: </table></td></tr>
1.8 www 3267: ENDSUPFORM
3268: }
1.7 www 3269: }
1.286 albertel 3270: $r->print('</table>');
1.18 www 3271: if ($allowed) {
1.287 albertel 3272: $r->print('
3273: <form method="post" name="extimport" action="/adm/coursedocs">
3274: <input type="hidden" name="title" />
3275: <input type="hidden" name="url" />
3276: <input type="hidden" name="useform" />
3277: <input type="hidden" name="residx" />
3278: </form>');
1.18 www 3279: }
1.19 www 3280: } else {
1.188 raeburn 3281: unless ($upload_result eq 'phasetwo') {
1.19 www 3282: # -------------------------------------------------------- This is showdoc mode
1.188 raeburn 3283: $r->print("<h1>".&mt('Uploaded Document').' - '.
1.141 albertel 3284: &Apache::lonnet::gettitle($r->uri).'</h1><p>'.
1.286 albertel 3285: &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."</p><table>".
3286: &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'</table>');
1.188 raeburn 3287: }
1.19 www 3288: }
1.26 www 3289: }
1.224 albertel 3290: $r->print(&Apache::loncommon::end_page());
1.26 www 3291: return OK;
1.1 www 3292: }
3293:
1.224 albertel 3294:
3295: sub editing_js {
3296: my ($udom,$uname) = @_;
3297: my $now = time();
1.302 bisitz 3298: my %lt = &Apache::lonlocal::texthash(
3299: p_mnf => 'Name of New Folder',
3300: t_mnf => 'New Folder',
3301: p_mnp => 'Name of New Page',
3302: t_mnp => 'New Page',
1.305 bisitz 3303: p_mxu => 'Title for the Uploaded Score',
1.325.2.1 raeburn 3304: p_msp => 'Name of the Simple Course Page',
1.305 bisitz 3305: p_msb => 'Title for the Problem',
3306: p_mdb => 'Title for the Drop Box',
1.325.2.1 raeburn 3307: p_mbb => 'Title for the Discussion Board',
1.302 bisitz 3308: p_mab => "Enter user:domain for User's 'About Me' Page",
3309: p_mab2 => "About [_99]",
3310: p_mab_alrt1 => 'Not a valid user:domain',
3311: p_mab_alrt2 => 'Please enter both user and domain in the format user:domain',
3312: p_chn => 'New Title',
3313: p_rmr1 => 'WARNING: Removing a resource makes associated grades and scores inaccessible!',
3314: p_rmr2a => 'Remove[_99]',
3315: p_rmr2b => '?[_99]',
1.303 raeburn 3316: p_ctr1a => 'WARNING: Cutting a resource makes associated grades and scores inaccessible!',
3317: p_ctr1b => 'Grades remain inaccessible if resource is pasted into another folder.',
1.302 bisitz 3318: p_ctr2a => 'Cut[_98]',
3319: p_ctr2b => '?[_98]'
3320: );
1.224 albertel 3321:
3322: return <<ENDNEWSCRIPT;
3323: function makenewfolder(targetform,folderseq) {
1.302 bisitz 3324: var foldername=prompt('$lt{"p_mnf"}','$lt{"t_mnf"}');
1.224 albertel 3325: if (foldername) {
1.236 albertel 3326: targetform.importdetail.value=escape(foldername)+"="+folderseq;
1.224 albertel 3327: targetform.submit();
3328: }
3329: }
3330:
3331: function makenewpage(targetform,folderseq) {
1.302 bisitz 3332: var pagename=prompt('$lt{"p_mnp"}','$lt{"t_mnp"}');
1.224 albertel 3333: if (pagename) {
1.236 albertel 3334: targetform.importdetail.value=escape(pagename)+"="+folderseq;
1.224 albertel 3335: targetform.submit();
3336: }
3337: }
3338:
3339: function makenewext(targetname) {
3340: this.document.forms.extimport.useform.value=targetname;
1.287 albertel 3341: this.document.forms.extimport.title.value='';
3342: this.document.forms.extimport.url.value='';
3343: this.document.forms.extimport.residx.value='';
3344: window.open('/adm/rat/extpickframe.html');
3345: }
3346:
3347: function edittext(targetname,residx,title,url) {
3348: this.document.forms.extimport.useform.value=targetname;
3349: this.document.forms.extimport.residx.value=residx;
3350: this.document.forms.extimport.url.value=url;
3351: this.document.forms.extimport.title.value=title;
1.224 albertel 3352: window.open('/adm/rat/extpickframe.html');
3353: }
3354:
3355: function makeexamupload() {
1.302 bisitz 3356: var title=prompt('$lt{"p_mxu"}');
1.224 albertel 3357: if (title) {
3358: this.document.forms.newexamupload.importdetail.value=
1.236 albertel 3359: escape(title)+'=/res/lib/templates/examupload.problem';
1.224 albertel 3360: this.document.forms.newexamupload.submit();
3361: }
3362: }
3363:
3364: function makesmppage() {
1.302 bisitz 3365: var title=prompt('$lt{"p_msp"}');
1.224 albertel 3366: if (title) {
3367: this.document.forms.newsmppg.importdetail.value=
1.236 albertel 3368: escape(title)+'=/adm/$udom/$uname/$now/smppg';
1.224 albertel 3369: this.document.forms.newsmppg.submit();
3370: }
3371: }
3372:
3373: function makesmpproblem() {
1.302 bisitz 3374: var title=prompt('$lt{"p_msb"}');
1.224 albertel 3375: if (title) {
3376: this.document.forms.newsmpproblem.importdetail.value=
1.236 albertel 3377: escape(title)+'=/res/lib/templates/simpleproblem.problem';
1.224 albertel 3378: this.document.forms.newsmpproblem.submit();
3379: }
3380: }
3381:
3382: function makedropbox() {
1.302 bisitz 3383: var title=prompt('$lt{"p_mdb"}');
1.224 albertel 3384: if (title) {
3385: this.document.forms.newdropbox.importdetail.value=
1.236 albertel 3386: escape(title)+'=/res/lib/templates/DropBox.problem';
1.224 albertel 3387: this.document.forms.newdropbox.submit();
3388: }
3389: }
3390:
3391: function makebulboard() {
1.302 bisitz 3392: var title=prompt('$lt{"p_mbb"}');
1.224 albertel 3393: if (title) {
3394: this.document.forms.newbul.importdetail.value=
1.236 albertel 3395: escape(title)+'=/adm/$udom/$uname/$now/bulletinboard';
1.224 albertel 3396: this.document.forms.newbul.submit();
3397: }
3398: }
3399:
3400: function makeabout() {
1.303 raeburn 3401: var user=prompt("$lt{'p_mab'}");
1.224 albertel 3402: if (user) {
3403: var comp=new Array();
1.236 albertel 3404: comp=user.split(':');
1.224 albertel 3405: if ((typeof(comp[0])!=undefined) && (typeof(comp[1])!=undefined)) {
3406: if ((comp[0]) && (comp[1])) {
3407: this.document.forms.newaboutsomeone.importdetail.value=
1.302 bisitz 3408: '$lt{"p_mab2"}'+escape(user)+'=/adm/'+comp[1]+'/'+comp[0]+'/aboutme';
1.224 albertel 3409: this.document.forms.newaboutsomeone.submit();
3410: } else {
1.302 bisitz 3411: alert("$lt{'p_mab_alrt1'}");
1.224 albertel 3412: }
3413: } else {
1.302 bisitz 3414: alert("$lt{'p_mab_alrt2'}");
1.224 albertel 3415: }
3416: }
3417: }
3418:
3419: function makeims() {
3420: var caller = document.forms.ims.folder.value;
3421: var newlocation = "/adm/imsimportdocs?folder="+caller+"&phase=one";
3422: newWindow = window.open("","IMSimport","HEIGHT=700,WIDTH=750,scrollbars=yes");
3423: newWindow.location.href = newlocation;
3424: }
3425:
3426:
3427: function finishpick() {
3428: var title=this.document.forms.extimport.title.value;
3429: var url=this.document.forms.extimport.url.value;
3430: var form=this.document.forms.extimport.useform.value;
1.287 albertel 3431: var residx=this.document.forms.extimport.residx.value;
3432: eval('this.document.forms.'+form+'.importdetail.value="'+title+'='+url+'='+residx+'";this.document.forms.'+form+'.submit();');
1.224 albertel 3433: }
3434:
3435: function changename(folderpath,index,oldtitle,container,pagesymb) {
1.302 bisitz 3436: var title=prompt('$lt{"p_chn"}',oldtitle);
1.224 albertel 3437: if (title) {
1.281 albertel 3438: this.document.forms.renameform.markcopy.value=-1;
1.224 albertel 3439: this.document.forms.renameform.title.value=title;
3440: this.document.forms.renameform.cmd.value='rename_'+index;
3441: if (container == 'sequence') {
3442: this.document.forms.renameform.folderpath.value=folderpath;
3443: }
3444: if (container == 'page') {
3445: this.document.forms.renameform.pagepath.value=folderpath;
3446: this.document.forms.renameform.pagesymb.value=pagesymb;
3447: }
3448: this.document.forms.renameform.submit();
3449: }
3450: }
3451:
1.291 albertel 3452: function removeres(folderpath,index,oldtitle,container,pagesymb,skip_confirm) {
1.302 bisitz 3453: if (skip_confirm || confirm('$lt{"p_rmr1"}\\n\\n$lt{"p_rmr2a"} "'+oldtitle+'" $lt{"p_rmr2b"}')) {
1.281 albertel 3454: this.document.forms.renameform.markcopy.value=-1;
1.224 albertel 3455: this.document.forms.renameform.cmd.value='del_'+index;
3456: if (container == 'sequence') {
3457: this.document.forms.renameform.folderpath.value=folderpath;
3458: }
3459: if (container == 'page') {
3460: this.document.forms.renameform.pagepath.value=folderpath;
3461: this.document.forms.renameform.pagesymb.value=pagesymb;
3462: }
3463: this.document.forms.renameform.submit();
3464: }
3465: }
3466:
1.291 albertel 3467: function cutres(folderpath,index,oldtitle,container,pagesymb,folder,skip_confirm) {
1.303 raeburn 3468: if (skip_confirm || confirm('$lt{"p_ctr1a"}\\n$lt{"p_ctr1b"}\\n\\n$lt{"p_ctr2a"} "'+oldtitle+'" $lt{"p_ctr2b"}')) {
1.224 albertel 3469: this.document.forms.renameform.cmd.value='cut_'+index;
3470: this.document.forms.renameform.markcopy.value=index;
1.281 albertel 3471: this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224 albertel 3472: if (container == 'sequence') {
3473: this.document.forms.renameform.folderpath.value=folderpath;
3474: }
3475: if (container == 'page') {
3476: this.document.forms.renameform.pagepath.value=folderpath;
3477: this.document.forms.renameform.pagesymb.value=pagesymb;
3478: }
3479: this.document.forms.renameform.submit();
3480: }
3481: }
3482:
1.281 albertel 3483: function markcopy(folderpath,index,oldtitle,container,pagesymb,folder) {
1.224 albertel 3484: this.document.forms.renameform.markcopy.value=index;
1.281 albertel 3485: this.document.forms.renameform.copyfolder.value=folder+'.'+container;
1.224 albertel 3486: if (container == 'sequence') {
3487: this.document.forms.renameform.folderpath.value=folderpath;
3488: }
3489: if (container == 'page') {
3490: this.document.forms.renameform.pagepath.value=folderpath;
3491: this.document.forms.renameform.pagesymb.value=pagesymb;
3492: }
3493: this.document.forms.renameform.submit();
3494: }
3495:
3496: ENDNEWSCRIPT
3497: }
1.1 www 3498: 1;
3499: __END__
1.315 jms 3500:
1.317 jms 3501:
3502: =head1 NAME
3503:
3504: Apache::londocs.pm
3505:
3506: =head1 SYNOPSIS
3507:
3508: This is part of the LearningOnline Network with CAPA project
3509: described at http://www.lon-capa.org.
3510:
3511: =head1 SUBROUTINES
3512:
3513: =over
3514:
3515: =item %help=()
3516:
3517: Available help topics
3518:
3519: =item mapread()
3520:
3521: Mapread read maps into LONCAPA::map:: global arrays
3522: @order and @resources, determines status
3523: sets @order - pointer to resources in right order
3524: sets @resources - array with the resources with correct idx
3525:
3526: =item authorhosts()
3527:
3528: Return hash with valid author names
3529:
3530: =item dumpbutton()
3531:
3532: Generate "dump" button
3533:
3534: =item clean()
3535:
3536: =item dumpcourse()
3537:
3538: Actually dump course
3539:
3540:
3541: =item exportbutton()
3542:
3543: Generate "export" button
3544:
3545: =item exportcourse()
3546:
3547: =item create_ims_store()
3548:
3549: =item build_package()
3550:
3551: =item get_dependencies()
3552:
3553: =item process_content()
3554:
3555: =item replicate_content()
3556:
3557: =item extract_media()
3558:
3559: =item store_template()
3560:
3561: =item group_import()
3562:
3563: Imports the given (name, url) resources into the course
3564: coursenum, coursedom, and folder must precede the list
3565:
3566: =item breadcrumbs()
3567:
3568: =item log_docs()
3569:
3570: =item docs_change_log()
3571:
3572: =item update_paste_buffer()
3573:
3574: =item print_paste_buffer()
3575:
3576: =item do_paste_from_buffer()
3577:
3578: =item update_parameter()
3579:
3580: =item handle_edit_cmd()
3581:
3582: =item editor()
3583:
3584: =item process_file_upload()
3585:
3586: =item process_secondary_uploads()
3587:
3588: =item is_supplemental_title()
3589:
3590: =item parse_supplemental_title()
3591:
3592: =item entryline()
3593:
3594: =item tiehash()
3595:
3596: =item untiehash()
3597:
3598: =item checkonthis()
3599:
3600: check on this
3601:
3602: =item verifycontent()
3603:
3604: Verify Content
3605:
3606: =item devalidateversioncache() & checkversions()
3607:
3608: Check Versions
3609:
3610: =item mark_hash_old()
3611:
3612: =item is_hash_old()
3613:
3614: =item changewarning()
3615:
3616: =item init_breadcrumbs()
3617:
3618: Breadcrumbs for special functions
1.315 jms 3619:
3620: =back
3621:
3622: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>