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