version 1.32, 2011/10/31 01:25:32
|
version 1.35, 2012/10/29 17:38:55
|
Line 28 package Apache::testbankimport;
|
Line 28 package Apache::testbankimport;
|
|
|
use strict; |
use strict; |
use Apache::Constants qw(:common :http :methods); |
use Apache::Constants qw(:common :http :methods); |
use Apache::loncacc; |
|
use Apache::loncommon(); |
use Apache::loncommon(); |
use Apache::lonnet; |
use Apache::lonnet; |
use HTML::Entities(); |
use HTML::Entities(); |
Line 485 function backPage() {
|
Line 484 function backPage() {
|
|
|
# ---------------------------------------------------------------- Display Zero |
# ---------------------------------------------------------------- Display Zero |
sub display_zero { |
sub display_zero { |
my ($r,$uname,$fn,$page,$webpath) = @_; |
my ($r,$fn,$page,$webpath) = @_; |
my $go_default = 'NextPage'; |
my $go_default = 'NextPage'; |
if ($fn eq '') { |
if ($fn eq '') { |
$r->print('<b>'.&mt('Incomplete file upload').'</b> '.&mt('Return to the [_1]construction space menu[_2] to upload a file','<a href="'.$webpath.'">','</a>')); |
$r->print('<b>'.&mt('Incomplete file upload').'</b> '.&mt('Return to the [_1]construction space menu[_2] to upload a file','<a href="'.$webpath.'">','</a>')); |
Line 512 sub display_zero {
|
Line 511 sub display_zero {
|
&Apache::lonhtmlcommon::topic_bar(1,&mt('Optional: create a sub-directory in which the testbank questions will be saved')). |
&Apache::lonhtmlcommon::topic_bar(1,&mt('Optional: create a sub-directory in which the testbank questions will be saved')). |
&mt('By default, LON-CAPA problems generated from the testbank file will be stored in the current directory.').' '.&mt('To store them in a new sub-directory:'). |
&mt('By default, LON-CAPA problems generated from the testbank file will be stored in the current directory.').' '.&mt('To store them in a new sub-directory:'). |
' <input type="button" name="createdir" value="'.&mt('Create sub-directory').'" onClick="javascript:createWin()" />'. |
' <input type="button" name="createdir" value="'.&mt('Create sub-directory').'" onClick="javascript:createWin()" />'. |
&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath).' |
&page_footer($env{'form.newdir'},$fn,$page,$webpath).' |
</form>'); |
</form>'); |
} |
} |
|
|
# ---------------------------------------------------------------- Display One |
# ---------------------------------------------------------------- Display One |
|
|
sub display_one { |
sub display_one { |
my ($r,$uname,$fn,$page,$textref,$header) = @_; |
my ($r,$fn,$page,$textref,$header) = @_; |
my %topics; |
my %topics; |
$topics{2} = &mt('Select the format of the question number - e.g., 1, 1., 1), (1 or (1) - ').' |
$topics{2} = &mt('Select the format of the question number - e.g., 1, 1., 1), (1 or (1) - ').' |
<select name="qnumformat"> |
<select name="qnumformat"> |
Line 566 sub display_one {
|
Line 565 sub display_one {
|
&mt('4 multiple choice questions').'<br />'. |
&mt('4 multiple choice questions').'<br />'. |
&mt('3 essay questions').'</blockquote></p><p>'. |
&mt('3 essay questions').'</blockquote></p><p>'. |
&mt('You will indicate the question type and the question number range for each of the blocks on the next page.').'</p><br />'. |
&mt('You will indicate the question type and the question number range for each of the blocks on the next page.').'</p><br />'. |
&page_footer($env{'form.newdir'},$uname,$fn,$page).' |
&page_footer($env{'form.newdir'},$fn,$page).' |
</form>'); |
</form>'); |
return; |
return; |
} |
} |
Line 574 sub display_one {
|
Line 573 sub display_one {
|
# ---------------------------------------------------------------- Display Two |
# ---------------------------------------------------------------- Display Two |
|
|
sub display_two { |
sub display_two { |
my ($r,$uname,$fn,$page,$textref,$header,$qcount) = @_; |
my ($r,$fn,$page,$textref,$header,$qcount) = @_; |
my $blocks = $env{'form.blocks'}; |
my $blocks = $env{'form.blocks'}; |
my $qnumformat = $env{'form.qnumformat'}; |
my $qnumformat = $env{'form.qnumformat'}; |
my @types = ("MC","MA","TF","Ess","FIB","Ord"); |
my @types = ("MC","MA","TF","Ess","FIB","Ord"); |
Line 658 sub display_two {
|
Line 657 sub display_two {
|
&mt('For <i>ranking</i> questions you must use the <b>Answer format</b> column to choose the separator used between the (ranked) answers.').'</li></ul> |
&mt('For <i>ranking</i> questions you must use the <b>Answer format</b> column to choose the separator used between the (ranked) answers.').'</li></ul> |
<input type="hidden" name="blocks" value="'.$blocks.'" /> |
<input type="hidden" name="blocks" value="'.$blocks.'" /> |
<input type="hidden" name="qnumformat" value="'.$qnumformat.'" />'. |
<input type="hidden" name="qnumformat" value="'.$qnumformat.'" />'. |
&page_footer($env{'form.newdir'},$uname,$fn,$page).' |
&page_footer($env{'form.newdir'},$fn,$page).' |
</form>'); |
</form>'); |
return; |
return; |
} |
} |
|
|
# ---------------------------------------------------------------- Display Three |
# ---------------------------------------------------------------- Display Three |
sub display_three { |
sub display_three { |
my ($r,$uname,$fn,$page,$textref,$res,$header,$urlpath,$qcount) = @_; |
my ($r,$fn,$page,$textref,$res,$header,$webpath,$qcount) = @_; |
my $qnumformat = $env{'form.qnumformat'}; |
my $qnumformat = $env{'form.qnumformat'}; |
my $filename = $env{'form.filename'}; |
my $filename = $env{'form.filename'}; |
my $source = $env{'form.go'}; |
my $source = $env{'form.go'}; |
Line 715 sub display_three {
|
Line 714 sub display_three {
|
if ($header ne '') { |
if ($header ne '') { |
$showheader = &HTML::Entities::decode($header); |
$showheader = &HTML::Entities::decode($header); |
if ($res eq 'text/html') { |
if ($res eq 'text/html') { |
$showheader = &build_image_url($urlpath,$showheader); |
$showheader = &build_image_url($webpath,$showheader); |
} |
} |
} |
} |
} |
} |
Line 764 sub display_three {
|
Line 763 sub display_three {
|
if (($res eq 'application/rtf') || ($res eq 'text/html')) { |
if (($res eq 'application/rtf') || ($res eq 'text/html')) { |
$showqn = &HTML::Entities::decode($showqn); |
$showqn = &HTML::Entities::decode($showqn); |
if ($res eq 'text/html') { |
if ($res eq 'text/html') { |
$showqn = &build_image_url($urlpath,$showqn); |
$showqn = &build_image_url($webpath,$showqn); |
} |
} |
} |
} |
$r->print(&Apache::loncommon::start_data_table_row(). |
$r->print(&Apache::loncommon::start_data_table_row(). |
Line 808 sub display_three {
|
Line 807 sub display_three {
|
if ($res eq 'application/rtf' || $res eq 'text/html') { |
if ($res eq 'application/rtf' || $res eq 'text/html') { |
$showfoil = &HTML::Entities::decode($showfoil); |
$showfoil = &HTML::Entities::decode($showfoil); |
if ($res eq 'text/html') { |
if ($res eq 'text/html') { |
$showfoil = &build_image_url($urlpath,$showfoil); |
$showfoil = &build_image_url($webpath,$showfoil); |
} |
} |
} |
} |
$r->print("$foiltag $showfoil<br />\n"); |
$r->print("$foiltag $showfoil<br />\n"); |
Line 859 sub display_three {
|
Line 858 sub display_three {
|
<input type="hidden" name="ansr_'.$i.'" value="'.$ansrtypes[$i].'" />'); |
<input type="hidden" name="ansr_'.$i.'" value="'.$ansrtypes[$i].'" />'); |
} |
} |
} |
} |
$r->print('</p>'.&page_footer($env{'form.newdir'},$uname,$fn,$page).' |
$r->print('</p>'.&page_footer($env{'form.newdir'},$fn,$page).' |
</form>'); |
</form>'); |
} |
} |
|
|
# ---------------------------------------------------------------- Final Display |
# ---------------------------------------------------------------- Final Display |
sub final_display { |
sub final_display { |
my ($r,$uname,$fn,$page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) = @_; |
my ($r,$fn,$page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) = @_; |
my $qnumformat = $env{'form.qnumformat'}; |
my $qnumformat = $env{'form.qnumformat'}; |
my $blocks = $env{'form.blocks'}; |
my $blocks = $env{'form.blocks'}; |
my $question_id = ''; |
my $question_id = ''; |
Line 1042 sub final_display {
|
Line 1041 sub final_display {
|
if (@createprobs == 0) { |
if (@createprobs == 0) { |
$state = 'unchecked'; |
$state = 'unchecked'; |
$r->print('<p>'.&mt('No questions were selected for conversion.').'</p>'. |
$r->print('<p>'.&mt('No questions were selected for conversion.').'</p>'. |
&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>'); |
&page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).'</form>'); |
} elsif (($destdir ne '') && (-e $destdir)) { |
} elsif (($destdir ne '') && (-e $destdir)) { |
my (@qn_file,@result,@numid); |
my (@qn_file,@result,@numid); |
my $qcount = 0; |
my $qcount = 0; |
Line 1130 sub final_display {
|
Line 1129 sub final_display {
|
$r->print('<p>'.&mt('The following files already existed, and were not overwritten so these problems generated from the testbank have not been saved:').'<br />'.$existing.'</p>'); |
$r->print('<p>'.&mt('The following files already existed, and were not overwritten so these problems generated from the testbank have not been saved:').'<br />'.$existing.'</p>'); |
$state = 'existing'; |
$state = 'existing'; |
} |
} |
$r->print(&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>'); |
$r->print(&page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).'</form>'); |
} else { |
} else { |
$state = 'nodir'; |
$state = 'nodir'; |
$r->print('<p>'.&mt('No destination directory was available so import of questions could not proceed.').'</p>'. |
$r->print('<p>'.&mt('No destination directory was available so import of questions could not proceed.').'</p>'. |
&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>'); |
&page_footer($env{'form.newdir'},$fn,$page,$webpath,$subdir,$state).'</form>'); |
} |
} |
return; |
return; |
} |
} |
Line 1159 sub show_uploaded_data {
|
Line 1158 sub show_uploaded_data {
|
} |
} |
|
|
sub page_footer { |
sub page_footer { |
my ($newdir,$uname,$fn,$page,$webpath,$subdir,$state) = @_; |
my ($newdir,$fn,$page,$webpath,$subdir,$state) = @_; |
my $prevval = &mt('Previous Page'); |
my $prevval = &mt('Previous Page'); |
my $nextval = &mt('Next Page'); |
my $nextval = &mt('Next Page'); |
my $prevclick = 'javascript:backPage();'; |
my $prevclick = 'javascript:backPage();'; |
Line 1184 sub page_footer {
|
Line 1183 sub page_footer {
|
} |
} |
my $output = ' |
my $output = ' |
<input type="hidden" name="newdir" value="'.&HTML::Entities::encode($newdir,'<>&"').'" /> |
<input type="hidden" name="newdir" value="'.&HTML::Entities::encode($newdir,'<>&"').'" /> |
<input type="hidden" name="uploaduname" value="'.$uname.'" /> |
|
<input type="hidden" name="filename" value="'.$fn.'" /> |
<input type="hidden" name="filename" value="'.$fn.'" /> |
<input type="hidden" name="page" value="'.$page.'" /> |
<input type="hidden" name="page" value="'.$page.'" /> |
<input type="hidden" name="phase" value="three" /> |
<input type="hidden" name="phase" value="three" /> |
Line 1604 sub probfile_name {
|
Line 1602 sub probfile_name {
|
} |
} |
|
|
sub file_error { |
sub file_error { |
my ($r,$uname,$fn,$current_page,$webpath,$res) = @_; |
my ($r,$fn,$current_page,$webpath,$res) = @_; |
$r->print('<p><form name="display" method="post" action="/adm/testbank">'.&mt('The file you uploaded does not appear to be in the correct format.'). |
$r->print('<p><form name="display" method="post" action="/adm/testbank">'.&mt('The file you uploaded does not appear to be in the correct format.'). |
'</p><p>'.&mt('Extraction of questions is only possible for the following file types:'). |
'</p><p>'.&mt('Extraction of questions is only possible for the following file types:'). |
'<ul><li>'.&mt('plain text').'</li><li>RTF</li><li>HTML</li></ul>'. |
'<ul><li>'.&mt('plain text').'</li><li>RTF</li><li>HTML</li></ul>'. |
&mt('The file type identified for the file you uploaded is [_1].','<b>'.$res.'</b>').'</p>'); |
&mt('The file type identified for the file you uploaded is [_1].','<b>'.$res.'</b>').'</p>'); |
$r->print(&page_footer($env{'form.newdir'},$uname,$fn,$current_page,$webpath,undef,'badfile'). |
$r->print(&page_footer($env{'form.newdir'},$fn,$current_page,$webpath,undef,'badfile'). |
'</form>'); |
'</form>'); |
return; |
return; |
} |
} |
|
|
sub parse_datafile { |
sub parse_datafile { |
my ($r,$uname,$filename,$pathname,$dirpath,$urlpath,$page_name,$subdir,$timestamp) = @_; |
my ($r,$filename,$dirpath,$webpath,$page_name,$subdir,$timestamp) = @_; |
my ($badfile,$res,%allfiles,%codebase); |
my ($badfile,$res,%allfiles,%codebase); |
my $mm = new File::MMagic; |
my $mm = new File::MMagic; |
my ($text,$header,$css,$js); |
my ($text,$header,$css,$js); |
Line 1630 sub parse_datafile {
|
Line 1628 sub parse_datafile {
|
my $html = ''; |
my $html = ''; |
my $image_uri = $timestamp; |
my $image_uri = $timestamp; |
if ($page_name eq 'Target') { |
if ($page_name eq 'Target') { |
$image_uri = $urlpath.'/'.$timestamp; |
$image_uri = "$webpath/$timestamp"; |
} |
} |
my $image_dir; |
my $image_dir; |
if ($page_name eq 'Blocks') { |
if ($page_name eq 'Blocks') { |
Line 1768 sub parse_htmlcontent {
|
Line 1766 sub parse_htmlcontent {
|
} |
} |
|
|
sub build_image_url { |
sub build_image_url { |
my ($urlpath,$item) = @_; |
my ($webpath,$item) = @_; |
$item =~ s/(<img[^>]+src=["']?\s*)(\.?\.?\/?)/$1$urlpath/gsi; |
$item =~ s/(<img[^>]+src=["']?\s*)(\.?\.?\/?)/$1$webpath/gsi; |
return $item; |
return $item; |
} |
} |
|
|
sub print_header { |
sub print_header { |
my ($uname,$udom,$javascript,$loadentries,$title,$current_page,$pagesref, |
my ($uname,$udom,$javascript,$loadentries,$title,$current_page,$pagesref, |
$namesref) = @_; |
$namesref) = @_; |
my $brcrum = [{'href' => &Apache::loncommon::authorspace(), |
my $brcrum = [{'href' => &Apache::loncommon::authorspace("/priv/$udom/$uname/"), |
'text' => 'Construction Space'}]; |
'text' => 'Construction Space'}]; |
if ($env{'form.phase'} eq 'three') { |
if ($env{'form.phase'} eq 'three') { |
if (ref($pagesref) eq 'ARRAY') { |
if (ref($pagesref) eq 'ARRAY') { |
Line 1814 sub print_header {
|
Line 1812 sub print_header {
|
# ---------------------------------------------------------------- Main Handler |
# ---------------------------------------------------------------- Main Handler |
sub handler { |
sub handler { |
my $r=shift; |
my $r=shift; |
my $uname; |
|
my $udom; |
|
my $javascript = ''; |
|
my $page_name = ''; |
|
my $current_page = ''; |
|
my $qcount = ''; |
|
my $title = 'Upload testbank questions to Construction Space'; |
|
|
|
if ($env{'form.uploaduname'}) { |
my $fn=$env{'form.filename'}; |
$env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'. |
|
$env{'form.filename'}; |
if ($env{'form.filename1'}) { |
} |
$fn=$env{'form.filename1'}.$env{'form.filename2'}; |
($uname,$udom)= |
|
&Apache::loncacc::constructaccess($env{'form.filename'}); |
|
unless (($uname ne '') && ($udom ne '')) { |
|
$r->log_reason($uname.':'.$udom.' trying to convert testbank file '. |
|
$env{'form.filename'}.' - not authorized',$r->filename); |
|
return HTTP_NOT_ACCEPTABLE; |
|
} |
} |
|
$fn=~s{\+}{}g; |
|
|
my ($fn,$filename); |
unless ($fn) { |
if ($env{'form.filename'}) { |
|
$fn=$env{'form.filename'}; |
|
$fn=~s/^https?\:\/\/[^\/]+\///; |
|
$fn=~s/^\///; |
|
$fn=~s{(~|priv/)($LONCAPA::username_re)}{}; |
|
$fn=~s/\/+/\//g; |
|
} else { |
|
$r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}. |
$r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}. |
' unspecified filename for upload', $r->filename); |
' unspecified filename for upload', $r->filename); |
return HTTP_NOT_FOUND; |
return HTTP_NOT_FOUND; |
} |
} |
|
|
|
my ($uname,$udom) = &Apache::lonnet::constructaccess($fn); |
|
if (($uname eq '') || ($udom eq '')) { |
|
$r->log_reason($uname.':'.$udom.' trying to convert testbank file '. |
|
$fn.' - not authorized',$r->filename); |
|
return HTTP_NOT_ACCEPTABLE; |
|
} |
|
|
|
my $javascript = ''; |
|
my $page_name = ''; |
|
my $current_page = ''; |
|
my $qcount = ''; |
|
my $title = 'Upload testbank questions to Construction Space'; |
|
|
# ----------------------------------------------------------- Start page output |
# ----------------------------------------------------------- Start page output |
&Apache::loncommon::content_type($r,'text/html'); |
&Apache::loncommon::content_type($r,'text/html'); |
$r->send_http_header; |
$r->send_http_header; |
|
|
my ($filename,$pathname) = &File::Basename::fileparse($fn); |
my ($filename,$webpath) = &File::Basename::fileparse($fn); |
my $webpath = '/priv/'.$udom.'/'.$uname.$pathname; |
|
my $dirpath = $r->dir_config('lonDocRoot').$webpath; |
my $dirpath = $r->dir_config('lonDocRoot').$webpath; |
my ($res,$subdir,$badfile,$textref,$header,$css,$js,%loadentries,@pages,%names); |
my ($res,$subdir,$badfile,$textref,$header,$css,$js,%loadentries,@pages,%names); |
|
|
Line 1875 sub handler {
|
Line 1866 sub handler {
|
} |
} |
} |
} |
($res,$badfile,$textref,$header,$css,$js) = |
($res,$badfile,$textref,$header,$css,$js) = |
&parse_datafile($r,$uname,$filename,$pathname,$dirpath,$webpath, |
&parse_datafile($r,$filename,$dirpath,$webpath,$page_name, |
$page_name,$subdir,$env{'form.timestamp'}); |
$subdir,$env{'form.timestamp'}); |
if ($page_name eq 'Welcome') { |
if ($page_name eq 'Welcome') { |
&jscript_zero($webpath,\$javascript); |
&jscript_zero($webpath,\$javascript); |
} elsif ($page_name eq 'Blocks') { |
} elsif ($page_name eq 'Blocks') { |
Line 1918 sub handler {
|
Line 1909 sub handler {
|
&jscript_zero($webpath,\$js); |
&jscript_zero($webpath,\$js); |
$js = '<script type="text/javascript">'."\n$js\n".'</script>'; |
$js = '<script type="text/javascript">'."\n$js\n".'</script>'; |
$r->print($js); |
$r->print($js); |
&display_zero($r,$uname,$fn,$current_page,$webpath); |
&display_zero($r,$fn,$current_page,$webpath); |
} elsif ($env{'form.phase'} eq 'three') { |
} elsif ($env{'form.phase'} eq 'three') { |
if ($env{'form.action'} eq 'upload_embedded') { |
if ($env{'form.action'} eq 'upload_embedded') { |
my ($result,$flag) = |
my ($result,$flag) = |
Line 1927 sub handler {
|
Line 1918 sub handler {
|
if ($flag eq 'modify_orightml') { |
if ($flag eq 'modify_orightml') { |
undef($page_name); |
undef($page_name); |
$r->print('<form name="testbankForm" method="post" action="/adm/testbank">'. |
$r->print('<form name="testbankForm" method="post" action="/adm/testbank">'. |
&page_footer('',$uname,$fn).'</form>'); |
&page_footer('',$fn).'</form>'); |
} |
} |
} |
} |
} |
} |
if ($badfile) { |
if ($badfile) { |
&file_error($r,$uname,$fn,$current_page,$webpath,$res); |
&file_error($r,$fn,$current_page,$webpath,$res); |
} else { |
} else { |
&display_zero ($r,$uname,$fn,$current_page,$webpath) if $page_name eq 'Welcome'; |
&display_zero ($r,$fn,$current_page,$webpath) if $page_name eq 'Welcome'; |
&display_one ($r,$uname,$fn,$current_page,$textref,$header) if $page_name eq 'Blocks'; |
&display_one ($r,$fn,$current_page,$textref,$header) if $page_name eq 'Blocks'; |
&display_two ($r,$uname,$fn,$current_page,$textref,$header,$qcount) if $page_name eq 'Format'; |
&display_two ($r,$fn,$current_page,$textref,$header,$qcount) if $page_name eq 'Format'; |
&display_three ($r,$uname,$fn,$current_page,$textref,$res,$header,$webpath,$qcount) if $page_name eq 'Target'; |
&display_three ($r,$fn,$current_page,$textref,$res,$header,$webpath,$qcount) if $page_name eq 'Target'; |
&final_display ($r,$uname,$fn,$current_page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) if $page_name eq 'Confirmation'; |
&final_display ($r,$fn,$current_page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) if $page_name eq 'Confirmation'; |
} |
} |
} elsif ($env{'form.phase'} eq 'two') { |
} elsif ($env{'form.phase'} eq 'two') { |
my ($result,$flag) = &Apache::lonupload::phasetwo($r,$fn,$uname,$udom,'testbank'); |
my ($result,$flag) = &Apache::lonupload::phasetwo($r,$fn,'testbank'); |
$r->print($result); |
$r->print($result); |
if ($flag eq 'ok') { |
if ($flag eq 'ok') { |
my $current_page = 0; |
my $current_page = 0; |
Line 1949 sub handler {
|
Line 1940 sub handler {
|
&jscript_zero($webpath,\$js); |
&jscript_zero($webpath,\$js); |
$js = '<script type="text/javascript">'."\n$js\n".'</script>'; |
$js = '<script type="text/javascript">'."\n$js\n".'</script>'; |
$r->print($js); |
$r->print($js); |
&display_zero($r,$uname,$fn,$current_page,$webpath); |
&display_zero($r,$fn,$current_page,$webpath); |
} elsif ($flag eq 'embedded') { |
} elsif ($flag eq 'embedded') { |
$r->print($js.'<form name="testbankForm" method="post" action="/adm/testbank">'. |
$r->print($js.'<form name="testbankForm" method="post" action="/adm/testbank">'. |
&page_footer('',$uname,$fn).'</form>'); |
&page_footer('',$fn).'</form>'); |
} |
} |
} else { |
} else { |
&Apache::lonupload::phaseone($r,$fn,$uname,$udom,'testbank'); |
&Apache::lonupload::phaseone($r,$fn,'testbank'); |
} |
} |
$r->print(&Apache::loncommon::end_page()); |
$r->print(&Apache::loncommon::end_page()); |
return OK; |
return OK; |