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