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