# The LearningOnline Network # Syllabus # # $Id: lonsyllabus.pm,v 1.138.2.5.2.2 2020/01/20 17:21:08 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonsyllabus; use strict; use Apache::lontemplate; use Apache::Constants qw(:common); use Apache::loncommon; use Apache::lonnet; use Apache::lontexconvert; use Apache::lonfeedback; use Apache::lonhtmlgateway; use Apache::lonannounce; use Apache::lonlocal; use Apache::lonhtmlcommon; use Apache::lonspeller(); use HTML::Entities(); sub handler { my $r = shift; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; my $target=$env{'form.grade_target'}; # --------------------------------------------------- Get course info from URL my (undef,undef,$cdom,$cnum)=split(/\//,$r->uri); # ------------------------------------------------------------ Get query string &Apache::loncommon::get_unprocessed_cgi ($ENV{'QUERY_STRING'},['register','forceedit','todocs', 'folderpath','title','only_body']); # ----------------------------------------------------- Is this even a course? my $homeserver=&Apache::lonnet::homeserver($cnum,$cdom); if ($homeserver eq 'no_host') { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &Apache::loncommon::simple_error_page($r,'No syllabus available', 'No syllabus available'); return OK; } elsif (!&Apache::lonnet::is_course($cdom,$cnum)) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &Apache::loncommon::simple_error_page($r,'No syllabus available', 'The course/community for which the syllabus was requested does not exist.'); return OK; } # ------------------------------------- There is such a course, get environment my %courseenv=&Apache::lonnet::dump('environment',$cdom,$cnum); my $crstype = &Apache::loncommon::course_type(); # --------------------------------------------------------------- Force Student my ($forceedit,$forcestudent); if ($env{'form.forceedit'}) { $forceedit=1; } if (!$forceedit) { $forcestudent=1; } # --------------------------------------------------------------- Check Privileges my $allowed = 0; if ($env{'user.environment'}) { # does this user have privileges to post, etc? if ($env{'request.course.id'} && $cdom eq $env{'course.'.$env{'request.course.id'}.'.domain'} && $cnum eq $env{'course.'.$env{'request.course.id'}.'.num'}) { $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'}); if ($forcestudent or $target eq 'tex') { $allowed=0; } } } # -------------------------------------------------- Let's see who handles this my $external=$courseenv{'externalsyllabus'}; my $uploaded=$courseenv{'uploadedsyllabus'}; my $minimal=$courseenv{'minimalsyllabus'}; if (($minimal =~/\w/) || ($uploaded =~/\w/)) { my ($item,$is_pdf); if ($minimal =~/\w/) { if ($external =~ m{\Q$minimal\E$}) { undef($external); } $item = $minimal; } elsif ($uploaded =~/\w/) { if ($external =~ m{\Q$uploaded\E$}) { undef($external); } $item = $uploaded; if ($item =~ /\.pdf$/i) { $is_pdf = 1; } } unless ($allowed && $forceedit) { my $file=&Apache::lonnet::filelocation("",$item); if ($file =~ /\.(tex|x?html?)$/) { my $filetype = $1; my $filecontents=&Apache::lonnet::getfile($file); if ($filecontents eq -1) { $r->print(&mt('Syllabus file unavailable')); } elsif ($filetype eq 'tex') { if ($target eq 'tex') { $r->print($filecontents); } else { my $texengine = $env{'form.texengine'}; if ($texengine eq '') { $texengine = 'tth'; } elsif (lc($texengine) eq 'jsmath') { $texengine = 'MathJax'; } my $result = &Apache::lontexconvert::converted(\$filecontents,$texengine); my %args; &get_breadcrumbs($cdom,$cnum,$crstype,\%args); if ($env{'form.only_body'}) { $args{'only_body'} = 1; } if ($env{'request.use_absolute'}) { $args{'use_absolute'} = $env{'request.use_absolute'}; } $r->print(&Apache::loncommon::start_page("Syllabus",undef,\%args). $result. &Apache::loncommon::end_page()); } } else { my %mystyle; unless ($target eq 'tex') { $target = 'web'; } &Apache::structuretags::reset_problem_globals(); my $oldfile = $env{'request.filename'}; $env{'request.filename'} = $item; my $result = &Apache::lonxml::xmlparse($r,$target,$filecontents, '',%mystyle); &Apache::structuretags::reset_problem_globals(); &Apache::lonhomework::finished_parsing(); $env{'request.filename'} = $oldfile; &Apache::lonxml::add_messages(\$result); $r->print($result); } } else { if ($target eq 'tex') { $r->print(&Apache::lonprintout::print_latex_header($env{'form.latex_type'}). ' \strut \\\\ \textbf{'.&mt('Syllabus').'} \strut \\\\ '. &mt('Unsupported file type.').' \strut \\\\ '. &mt('Print the syllabus directly from your web browser'). '\end{document}'); } else { my $brcrum; if ($env{'form.folderpath'} =~ /^supplemental/) { my $title = $env{'form.title'}; if ($title eq '') { $title = &mt('Syllabus'); } $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1); } $r->print(&Apache::lonwrapper::wrapper($r,$item,$brcrum,$env{'request.use_absolute'}, undef,$is_pdf,undef,'','',&mt('Syllabus'))); } } return OK; } } elsif ($external=~/\w/) { unless ($allowed && $forceedit) { if (($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public') && ($ENV{'SERVER_PORT'} == 443) && ($external =~ m{^http://}) && !($env{'form.usehttp'})) { unless (&Apache::lonnet::uses_sts()) { &redirect_to_http($r); return OK; } } if ($target eq 'tex') { $r->print(&Apache::lonprintout::print_latex_header($env{'form.latex_type'}). ' \strut \\\\ \textbf{'.&mt('Syllabus').'} \strut \\\\ '.$external.' '. ' \strut \\\\ '.&mt('Print the syllabus directly from your web browser'). '\end{document}'); } else { my $is_ext = 1; my ($is_pdf,$brcrum); if ($external =~ /\.pdf$/i) { $is_pdf = 1; } if ($env{'form.folderpath'} =~ /^supplemental/) { my $title = $env{'form.title'}; if ($title eq '') { $title = &mt('Syllabus'); } $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1); } $r->print(&Apache::lonwrapper::wrapper($r,$external,$brcrum,$env{'request.use_absolute'}, $is_ext,$is_pdf,undef,'','',&mt('Syllabus'))); } return OK; } } # ------------------------------------------------------------ Print the screen if ($target eq 'tex') { $r->print(&Apache::lonprintout::print_latex_header($env{'form.latex_type'})); } # ------------------------------ The buck stops here: internal syllabus display # --------------------------------------------------------- The syllabus fields my %syllabusfields=&Apache::lonlocal::texthash( 'aaa_instructorinfo' => 'Instructor Information', 'bbb_description' => 'Course Description', 'ccc_prereq' => 'Prerequisites', 'cdc_classhours' => 'Class Hours', 'ddd_officehours' => 'Office Hours', 'eee_helproom' => 'Helproom Hours', 'efe_projectinfo' => 'Project Information', 'fff_examinfo' => 'Exam Information', 'fgf_deadlines' => 'Deadlines', 'ggg_grading' => 'Grading Information', 'hhh_readings' => 'Readings', 'iii_coursepack' => 'Coursepack', 'jjj_weblinks' => 'Web Links', 'kkk_textbook' => 'Textbook', 'lll_includeurl' => 'URLs To Include in Syllabus'); # ---------------------------------------------------------- Load syllabus info my %syllabus=&Apache::lonnet::dump('syllabus',$cdom,$cnum); my ($output,%displayfields,%noshow); # This handler might be called anonymously ... # ----------------------------------------------------- Only if not public call if ($allowed) { if (($env{'form.choice'} =~ /^(template|minimal|url|file)$/) || ($env{'form.phase'} =~ /^(upload|check)_embedded$/)) { my $earlyout; ($earlyout,$uploaded,$external,$minimal,$output) = &save_changes($cnum,$cdom,$uploaded,$external,$minimal, \%syllabus,\%syllabusfields,\%courseenv); if (($env{'form.choice'} eq 'minimal') && ($minimal eq "/uploaded/$cdom/$cnum/portfolio/syllabus/loncapa.html")) { delete($env{'form.symb'}); delete($env{'request.symb'}); $r->internal_redirect("$minimal?editmode=1&forceedit=1"); return OK; } if ($earlyout) { if ($target ne 'tex') { &print_header($r,$cnum,$cdom,$crstype,$allowed,$forceedit, \%syllabus,\%syllabusfields); $r->print($output. &Apache::loncommon::end_page()); } return OK; } } } if ($target ne 'tex') { &print_header($r,$cnum,$cdom,$crstype,$allowed,$forceedit,\%syllabus, \%syllabusfields); $r->print($output); } # -------------------------------------------- Determine which fields are shown if ($syllabus{'uploaded.fields'}) { if ($syllabus{'uploaded.fields'} eq 'none') { foreach my $field (keys(%syllabusfields)) { $displayfields{$field} = ' style="display:none;"'; $noshow{$field} = 1; } } else { my %included; map { $included{$_} = 1; } split(/,/,$syllabus{'uploaded.fields'}); foreach my $field (keys(%syllabusfields)) { my ($prefix) = split(/_/,$field); if ($included{$prefix}) { $displayfields{$field} = ' style="display:block;"'; } else { $displayfields{$field} = ' style="display:none;"'; $noshow{$field} = 1; } } } } else { foreach my $field (keys(%syllabusfields)) { if ($syllabus{$field} ne '') { $displayfields{$field} = ' style="display:block;"'; } else { $displayfields{$field} = ' style="display:none;"'; } } } if ($allowed) { #---------------------------------- Print External URL Syllabus Info if editing if ($target ne 'tex') { my $hostname = &Apache::lonnet::hostname($homeserver); my $protocol = $Apache::lonnet::protocol{$homeserver}; $protocol = 'http' if ($protocol ne 'https'); my $link = $protocol.'://'.$hostname.$r->uri; $r->print('
' .'' .'' .&mt('Public link (no log-in): [_1]',''.$link.'') .' '.&Apache::loncommon::help_open_topic('Syllabus_ExtLink') .'' .'
'."\n"); my $lonhost = $r->dir_config('lonHostID'); $r->print(&chooser($external,$uploaded,$minimal,$cdom,$cnum,$lonhost, \%syllabusfields,\%syllabus)); } } else { #--------------------------------------------- Print last update unless editing my $lastmod=$syllabus{'uploaded.lastmodified'}; $lastmod=($lastmod?&Apache::lonlocal::locallocaltime($lastmod):&mt('never')); my $who; if ($syllabus{'uploaded.lastmodified'}) { if (($env{'user.name'} ne 'public') && ($env{'user.domain'} ne 'public')) { $who = &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($syllabus{'uploaded.name'}, $syllabus{'uploaded.domain'}),$syllabus{'uploaded.name'}, $syllabus{'uploaded.domain'}); } else { # Public user? # Only display name of user, but no link to personal information page $who = &Apache::loncommon::plainname( $syllabus{'uploaded.name'}, $syllabus{'uploaded.domain'}); } } if ($target ne 'tex') { $r->print('
'.&mt('Last updated').': '. $lastmod . ' '. ($who ? &mt('by').' '.$who : '' ) . '
' ); } else { $r->print('\\\\ '.&mt('Last updated').': '.$lastmod.' '. ($who? &mt('by').'\\\\ '. &Apache::loncommon::plainname($syllabus{'uploaded.name'},$syllabus{'uploaded.domain'}) :'') .'\\\\'); } } #-------------------------------------------------------------- Print Headtitle if ($target ne 'tex') { my $display = 'block'; if ($external || $uploaded || $minimal) { $display = 'none'; } $r->print('
'. '

'.$courseenv{'description'}.'

'); if ($allowed) { $r->print('
'. '

'.&Apache::lonnet::domain($cdom,'description').'

'. '
'); # Print Help Text if editing at right side of screen $r->print('
'. &Apache::loncommon::help_open_topic('Uploaded_Templates_TextBoxes',&mt('Help with filling in text boxes')). '

'); } else { $r->print('

'.&Apache::lonnet::domain($cdom,'description').'

'); } } else { $r->print('\noindent{\large\textbf{'.$courseenv{'description'}.'}}\\\\\\\\\textbf{'. &Apache::lonnet::domain($cdom,'description').'}\\\\'); } # -------------------------------------------------------- Get course personnel my $hidepersonnel; if (($syllabus{'uploaded.fields'}) && (($syllabus{'uploaded.fields'} eq 'none') || ($syllabus{'uploaded.fields'} !~ /000/))) { $hidepersonnel = 1; } if ($target ne 'tex') { if ($allowed) { my $display = ' style="display:block;"'; if ($hidepersonnel) { $display = ' style="display:none;"'; } &Apache::lontemplate::print_start_template($r,&mt('Personnel'),'LC_Box', 'box_000_showpeople',$display); $r->print(&get_personnel($r,$target,$cdom,$cnum,$allowed,$crstype,\%syllabus)); &Apache::lontemplate::print_end_template($r); } else { unless ($hidepersonnel) { &Apache::lontemplate::print_start_template($r,&mt('Personnel'),'LC_Box'); $r->print(&get_personnel($r,$target,$cdom,$cnum,$allowed,$crstype,\%syllabus)); &Apache::lontemplate::print_end_template($r); } } } else { unless ($hidepersonnel) { $r->print(&get_personnel($r,$target,$cdom,$cnum,$allowed,$crstype,%syllabus)); } } # -------------------------------------------------------------- Announcements? my $day = &Apache::lonannounce::showday(time,2, &Apache::lonannounce::readcalendar($cdom.'_'.$cnum)); my $hidefeeds; if (($syllabus{'uploaded.fields'}) && (($syllabus{'uploaded.fields'} eq 'none') || ($syllabus{'uploaded.fields'} !~ /111/))) { $hidefeeds = 1; } if ($target ne 'tex') { if ($allowed) { my $display = ' style="display:block;"'; if ($hidefeeds) { $display = ' style="display:none;"'; } &Apache::lontemplate::print_start_template($r,&mt('RSS Feeds and Blogs'),'LC_Box', 'box_111_showrssfeeds',$display); my ($numfeeds,$hiddenfeeds,$rsslinktext); my $feeds=&Apache::lonrss::advertisefeeds($cnum,$cdom,$forceedit,\$numfeeds, \$hiddenfeeds); if ($numfeeds) { $r->print($feeds); $rsslinktext = &mt('New RSS Feed or Blog'); } else { my $msg = '
'. &mt("RSS Feeds and Blogs item is not included in a student's view of the syllabus."); if ($hiddenfeeds) { $r->print('

'. &mt('All feeds currently hidden'). $msg. '

'); } else { $r->print('

'. &mt('No current feeds'). $msg. '

'); } $rsslinktext = &mt('Manage Course RSS Feeds/Blogs'); if ($crstype eq 'Community') { $rsslinktext = &mt('Manage Community RSS Feeds/Blogs'); } } my $editurl= &Apache::lonnet::absolute_url().'/adm/'.$cdom.'/'.$cnum.'/_rss.html'; $r->print( ''.$rsslinktext.''); &Apache::lontemplate::print_end_template($r); } else { unless ($hidefeeds) { my $feeds = &Apache::lonrss::advertisefeeds($cnum,$cdom,$forceedit); if ($feeds ne '') { &Apache::lontemplate::print_start_template($r,&mt('RSS Feeds and Blogs'),'LC_Box'); $r->print($feeds); &Apache::lontemplate::print_end_template($r); } } } } else { $r->print(&Apache::lonxml::xmlparse($r,'tex',$day)); } # ---------------------------------------------------------------- Get syllabus if (($syllabus{'uploaded.lastmodified'}) || ($allowed)) { my $url_include_handler = sub { my ($r, $field, $message, $group, $data_ref, $fields_ref, $target, $allowed, $display) = @_; my %data = %{$data_ref}; my %fields = %{$fields_ref}; my $urls=$message; $message=''; foreach my $filelink (split(/\n/,$urls)) { my $output=''; # embed style? my ($curfext)=($filelink=~/\.([^\.]+)$/); my $embstyle=&Apache::loncommon::fileembstyle($curfext); if (($embstyle eq 'ssi') || ($curfext=~/\/$/)) {# make ssi call and remove everything but the body contents $output=&Apache::lonnet::ssi_body($filelink); } elsif ($embstyle eq 'img') {# embed as an image $output=''; } if ($output ne '') { if ($target ne 'tex') { $message.='

'.$output.'

'; } else { $message.=' '.&Apache::lonxml::xmlparse($r,'tex','

'.$output.'

').' '; } } } if ($allowed) { &Apache::lonfeedback::newline_to_br(\$urls); &Apache::lontemplate::print_start_template($r,$fields{$field}. &Apache::loncommon::help_open_topic('Syllabus_URLs'),'LC_Box', 'box_'.$field,$display); $r->print($urls); $r->print("
"); &Apache::lontemplate::print_textarea_template($r, $data{$field}, $field, Apache::lontemplate->RICH_TEXT_ALWAYS_OFF); &Apache::lontemplate::print_saveall_template($r); $r->print("
"); &Apache::lontemplate::print_end_template($r); } else { $r->print($message); } }; my %custom_hash = ( 'lll_includeurl' => $url_include_handler ); &Apache::lontemplate::print_template_fields($r, \%syllabus, \%syllabusfields, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML, \%custom_hash, undef,\%displayfields,\%noshow); if ($allowed) { $r->print('
'. &Apache::lonhtmlcommon::htmlareaselectactive()); } } else { if ($target ne 'tex') {$r->print('

');} else {$r->print('\par ');} $r->print(&mt('No syllabus information provided.')); if ($target ne 'tex') {$r->print('

');} } if ($target ne 'tex') { if ($env{'form.backto'} eq 'coursecatalog') { $r->print('
'. &Apache::lonhtmlcommon::echo_form_input(['backto','courseid']). '
'); } $r->print(&Apache::loncommon::end_page()); } else { $r->print('\end{document}'); } return OK; } sub print_header { my ($r,$cnum,$cdom,$crstype,$allowed,$forceedit,$syllabus,$syllabusfields) = @_; return unless ((ref($syllabus) eq 'HASH') || (ref($syllabusfields) eq 'HASH')); # ----------------------------------------------------------------- Make header my $rss_link = &Apache::lonrss::rss_link($cnum,$cdom); my $js; if ($env{'form.backto'} eq 'coursecatalog') { $js .= <<"ENDSCRIPT"; ENDSCRIPT } if ($allowed && $forceedit) { my $check_uncheck = &Apache::loncommon::check_uncheck_jscript(); my @fieldnames = sort(keys(%{$syllabusfields})); unshift(@fieldnames,'000_showpeople','111_showrssfeeds'); my (@checked,@unchecked); if ($syllabus->{'uploaded.fields'} eq 'none') { my $lastidx = scalar(@fieldnames)-1; @unchecked = (0..$lastidx); } elsif ($syllabus->{'uploaded.fields'}) { my %included; map { $included{$_} = 1; } split(/,/,$syllabus->{'uploaded.fields'}); for (my $i=0; $i<@fieldnames; $i++) { my ($prefix) = split(/_/,$fieldnames[$i]); if ($included{$prefix}) { push(@checked,$i); } else { push(@unchecked,$i); } } } else { @checked = (0,1); for (my $i=2; $i<@fieldnames; $i++) { if ($syllabus->{$fieldnames[$i]}) { push(@checked,$i); } else { push(@unchecked,$i); } } } my $fieldstr = "var fields = new Array('".join("','",@fieldnames)."');"; my $checkedstr = "var include = new Array('".join("','",@checked)."');"; my $uncheckedstr = "var exclude = new Array('".join("','",@unchecked)."');"; my $invurl = &mt('Invalid URL'); &js_escape(\$invurl); my $urlregexp = <<'ENDREGEXP'; /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i ENDREGEXP $js .= <<"ENDSCRIPT"; ENDSCRIPT } my $args = {'function' => undef, 'domain' => $cdom}; my $forcereg; if ($env{'form.register'}) { $forcereg = 1; $args->{'force_register'} = $forcereg; } if ($env{'form.backto'} eq 'coursecatalog') { &Apache::lonhtmlcommon::clear_breadcrumbs(); my $brcrum = [{href=>"javascript:ToCatalog();", text=>&mt('Course/Community Catalog'), no_mt=>1} ]; if ($env{'form.coursenum'} ne '') { push(@{$brcrum}, {href=>"javascript:ToCatalog('details')", text=>"Course details"}); } push(@{$brcrum}, {href=>$r->uri, text=>"Course syllabus"}); $args->{'bread_crumbs'} = $brcrum; } else { &get_breadcrumbs($cdom,$cnum,$crstype,$args); } if ($allowed) { my %loaditem = ( onload => 'setTemplateBoxes();', ); $args->{'add_entries'} = \%loaditem; } else { if ($env{'request.use_absolute'}) { $args->{'use_absolute'} = $env{'request.use_absolute'}; } } if ($env{'form.only_body'}) { $args->{'only_body'} = 1; } $args->{'hostname'} = $r->hostname(); my $start_page = &Apache::loncommon::start_page("Syllabus", $rss_link.$js,$args); if ($start_page) { $r->print($start_page); } } sub get_breadcrumbs{ my ($cdom,$cnum,$crstype,$args) = @_; return unless (ref($args) eq 'HASH'); if ($env{'form.folderpath'} =~ /^supplemental/) { my $title = $env{'form.title'}; if ($title eq '') { $title = &mt('Syllabus'); } my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1); if (ref($brcrum) eq 'ARRAY') { $args->{'bread_crumbs'} = $brcrum; } } else { if ((&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) && (($env{'form.symb'}) || ($env{'form.register'}))) { &Apache::lonhtmlcommon::clear_breadcrumbs(); } else { $args->{'bread_crumbs'} = [ {'href' => "/public/$cdom/$cnum/syllabus", 'text' => 'Syllabus'}, ]; } } return; } sub chooser { my ($external,$uploaded,$minimal,$cdom,$cnum,$lonhost,$fields,$values) = @_; my %lt = &Apache::lonlocal::texthash( 'type' => 'Syllabus Type', 'url' => 'External URL', 'file' => 'Uploaded file', 'minimal' => 'Minimal template', 'template' => 'Standard template', 'templateboxes' => 'Choose template items ... ', 'curr' => 'Current:', 'rep' => 'Replace:', 'upl' => 'Upload:', 'pr' => 'Preview', 'save' => 'Save', 'sved' => 'Save and Edit', 'chourl' => 'External URL', 'chofile' => 'Uploaded syllabus file', 'parse' => 'Upload embedded images/multimedia files if HTML file', ); my %checked = ( file => '', minimal => '', url => '', template => '', ); my %display = ( file => 'none', minimal => 'none', url => 'none', templatebox => 'none', ); my $check = ' checked="checked" '; if ($uploaded) { $checked{'file'} = $check; $display{'file'} = 'block'; } elsif ($external) { $checked{'url'} = $check; $display{'url'} = 'block'; } elsif ($minimal) { $checked{'minimal'} = $check; $display{'minimal'} = 'block'; } else { $checked{'template'} = $check; $checked{'templatebox'} = $check; $display{'templatebox'} = 'block'; } my $protocol = ($ENV{'SERVER_PORT'} == 443?'https':'http'); my $output = '
'."\n". ''."\n". '
'.$lt{'type'}.''; foreach my $item ('minimal','template','url','file') { $output .= '
'; } $output .= '
'."\n". '
'."\n". '
'.$lt{'chourl'}.''."\n". ''.$lt{'pr'}.' '."\n". ''."\n". ' '."\n". '
'."\n". '
'."\n". '
'.$lt{'minimal'}.''; if ($minimal) { my ($absurl,$filename,$depbutton) = &syllabus_file_info($minimal,$cnum,$cdom,$lonhost,'minimal'); $output .= ''.$lt{'pr'}.''. ''. $depbutton; } else { $output .= &mt('Title of Syllabus Page:').' '. ''."\n". ' '."\n"; } $output .= '
'."\n". '
'."\n". '
'.$lt{'file'}.''; if ($uploaded) { my ($absurl,$filename,$depbutton) = &syllabus_file_info($uploaded,$cnum,$cdom,$lonhost,'file'); $output .= ''.$lt{'curr'}.' '. ''. ''.$filename.''.$depbutton. '

'.$lt{'rep'}; } else { $output .= $lt{'upl'}; } $output .= '
'."\n". ''. ''."\n". ' '. '
'. ''. '
'. '
'.$lt{'templateboxes'}. ' '. (' 'x2). ''. ''. &fields_check_uncheck($fields,$values). '

'. ''. '
'; $output .= '
'; return $output; } sub syllabus_file_info { my ($item,$cnum,$cdom,$lonhost,$context) = @_; my $hostname = &Apache::lonnet::hostname($lonhost); my $protocol = $Apache::lonnet::protocol{$lonhost}; $protocol = 'http' if ($protocol ne 'https'); my $absurl = $protocol.'://'.$hostname.$item; my ($filename) = ($item =~ m{([^/]+)$}); my $file=&Apache::lonnet::filelocation("",$item); my ($depbutton,$filetype,$editable); if ($file =~ /\.(xhtml|xml|tex|html|htm)$/) { $filetype=$1; } if ($filetype) { unless ($filetype eq 'tex') { $filetype='html'; } } if ($filetype eq 'html') { my $filecontents=&Apache::lonnet::getfile($file); unless ($filecontents eq -1) { my $mm = new File::MMagic; my $mimetype = $mm->checktype_contents($filecontents); if ($mimetype eq 'text/html') { my (%codebase,%allfiles); my $parse_result = &Apache::lonnet::extract_embedded_items($item,\%allfiles, \%codebase,\$filecontents); my $actionurl = "/public/$cdom/$cnum/syllabus"; my ($ignore,$num,$numpathchanges,$existing,$mapping) = &Apache::loncommon::ask_for_embedded_content($actionurl,undef,\%allfiles, \%codebase, {'context' => 'rewrites', 'ignore_remote_references' => 1,}); $editable = 1; } } } $depbutton = (' ' x 3). &editfile_button($item,$context,$editable). &editbutton_js(); return ($absurl,$filename,$depbutton); } sub fields_check_uncheck { my ($fields,$values) = @_; return unless ((ref($fields) eq 'HASH') && (ref($values) eq 'HASH')); my $numinrow = 4; my $table; my @fieldnames = sort(keys(%{$fields})); unshift(@fieldnames,'000_showpeople','111_showrssfeeds'); my $numfields = scalar(@fieldnames); my %included; if (($values->{'uploaded.fields'}) && ($values->{'uploaded.fields'} ne 'none')) { map { $included{$_} = 1; } split(/,/,$values->{'uploaded.fields'}); } for (my $i=0; $i<$numfields; $i++) { my ($name,$checked); if ($fieldnames[$i] eq '000_showpeople') { $name = &mt('Personnel'); } elsif ($fieldnames[$i] eq '111_showrssfeeds') { $name = &mt('RSS Feeds and Blogs'); } else { $name = $fields->{$fieldnames[$i]}; } if ($values->{'uploaded.fields'}) { unless ($values->{'uploaded.fields'} eq 'none') { my ($prefix) = split(/_/,$fieldnames[$i]); if ($included{$prefix}) { $checked = ' checked="checked"'; } } } else { if ($fieldnames[$i] eq '000_showpeople') { $checked = ' checked="checked"'; } elsif ($fieldnames[$i] eq '111_showrssfeeds') { $checked = ' checked="checked"'; } else { if ($values->{$fieldnames[$i]} ne '') { $checked = ' checked="checked"'; } } } my $rem = $i%($numinrow); if ($rem == 0) { if (($i > 0) && ($i < $numfields)) { $table .= ''; } if ($i < $numfields) { $table .= ''; } } if ($i == $numfields-1) { my $rem = $numfields%($numinrow); my $colsleft = $numinrow - $rem; if ($colsleft > 1) { $table .= ''; } else { $table .= ''; } } else { $table .= ''; } $table .= ''."\n"; } if ($table ne '') { my $rem = $numfields%($numinrow); my $colsleft = $numinrow - $rem; if ($colsleft > 1 ) { $table .= ' '; } elsif ($colsleft == 1) { $table .= ' '; } $table = ''.$table.'
'; } return $table; } sub get_personnel { my ($r,$target,$cdom,$cnum,$allowed,$crstype,$syllabus) = @_; my (%hiddenroles,%hiddenusers); if (ref($syllabus) eq 'HASH') { if (ref($syllabus->{'personnel'}) eq 'HASH') { if ($syllabus->{'personnel'}{'hiderole'}) { map { $hiddenroles{$_} = 1; } split(/,/,$syllabus->{'personnel'}{'hiderole'}); } if ($syllabus->{'personnel'}{'hideuser'}) { map { $hiddenusers{$_} = 1; } split(/,/,$syllabus->{'personnel'}{'hideuser'}); } } } my $output; my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum,1); if ($target ne 'tex') { if ($allowed) { $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). ''.&mt('Role hidden?').''.&mt('Role').''. ''.&mt('Personnel (hidden if checked)').''. &Apache::loncommon::end_data_table_header_row()); } else { $r->print(&Apache::lonhtmlcommon::start_pick_box()); } } else { $r->print('\begin{tabular}{|p{0.45\textwidth}|p{0.45\textwidth}|}\hline'); } my @personnel=sort(keys(%coursepersonnel)); my $lastpers=$personnel[$#personnel]; foreach my $element (@personnel) { unless ($allowed) { next if ($hiddenroles{$element}) } my ($role,$sec); if ($element =~ /:/) { ($role,$sec) = split(/:/,$element); } else { $role = $element; } my $roletext = &Apache::lonnet::plaintext($role,$crstype); if ($sec) { $roletext .=' ('.&Apache::lonlocal::mt('Section [_1]',$sec).')'; } if ($target ne 'tex') { if ($allowed) { my $checked; if ($hiddenroles{$element}) { $checked = ' checked="checked"'; } $r->print(&Apache::loncommon::start_data_table_row(). ''. ''. ''.$roletext.''); } else { $r->print(&Apache::lonhtmlcommon::row_title($roletext)); } } else { $r->print(' '.&Apache::lonxml::xmlparse($r,'tex',$roletext).' & '); } my @coursepersonlist; foreach my $user (split(/\,/,$coursepersonnel{$element})) { my ($puname,$pudom)=split(/\:/,$user); if ($target ne 'tex') { my $courseperson = &Apache::loncommon::plainname($puname,$pudom); my $checked; if ($hiddenusers{$element.'&'.$puname.':'.$pudom}) { $checked = ' checked="checked"'; } if ($allowed) { my $item = ''.(' 'x2).' '; push(@coursepersonlist,$item); } else { next if ($hiddenusers{$element.'&'.$puname.':'.$pudom}); if (($env{'user.name'} eq '') || ($env{'user.name'} eq 'public') || ($env{'user.domain'} eq '') || ($env{'user.domain'} eq 'public')) { push(@coursepersonlist,$courseperson); } else { push(@coursepersonlist,&Apache::loncommon::aboutmewrapper($courseperson, $puname,$pudom)); } } } else { push(@coursepersonlist,&Apache::loncommon::plainname($puname, $pudom).' '); } } if ($allowed) { $r->print(join('',@coursepersonlist)); } else { $r->print(join(', ',@coursepersonlist)); } if ($target ne 'tex') { if ($allowed) { $r->print(''.&Apache::loncommon::end_data_table_row()); } else { my $lastclose=$element eq $lastpers?1:0; $r->print(&Apache::lonhtmlcommon::row_closure($lastclose)); } } else { $r->print('\\\\ \hline'); } } if ($target ne 'tex') { if ($allowed) { $r->print(&Apache::loncommon::end_data_table()); } else { $r->print(&Apache::lonhtmlcommon::end_pick_box()); } } else { $r->print('\end{tabular}\\\\'); } return; } sub save_changes { my ($cnum,$cdom,$uploaded,$external,$minimal,$syllabus,$syllabusfields,$courseenv) = @_; my ($earlyout,$output); unless ((ref($syllabus) eq 'HASH') && (ref($syllabusfields) eq 'HASH') || (ref($courseenv) eq 'HASH')) { return ($earlyout,$uploaded,$external,$minimal,$output); } my ($was_ext,$is_ext,$putres); if ($external) { $was_ext = $external; } if (($env{'form.deleteuploaded_file'}) || ($env{'form.deleteuploaded_minimal'})) { my %storehash; if (($env{'form.choice'} eq 'file') && ($env{'form.deleteuploaded_file'}) && ($uploaded =~ /\w/)) { if ($courseenv->{'uploadedsyllabus'} =~ m{^\Q/uploaded/$cdom/$cnum/portfolio\E(/syllabus/.+)$}) { my $filename = $1; &update_access_permissions($cdom,$cnum,$filename); } &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.uploadedsyllabus'); &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.externalsyllabus'); $storehash{'uploadedsyllabus'} = ''; $storehash{'externalsyllabus'} = ''; $putres = &Apache::lonnet::put('environment',\%storehash,$cdom,$cnum); undef($uploaded); undef($external); } elsif (($env{'form.choice'} eq 'minimal') && ($env{'form.deleteuploaded_minimal'}) && ($minimal =~ /\w/)) { my $minimalurl = "/uploaded/$cdom/$cnum/portfolio/syllabus/loncapa.html"; if ($courseenv->{'minimalsyllabus'} eq "$minimalurl") { my $filecontents=&Apache::lonnet::getfile(&Apache::lonnet::filelocation("",$minimalurl)); unless ($filecontents eq -1) { $env{'form.output'} = $filecontents; &Apache::lonnet::finishuserfileupload($cnum,$cdom,'output', 'portfolio/syllabus/loncapa.html.bak'); $minimalurl = &default_minimal_syllabus($cnum,$cdom); } } &update_access_permissions($cdom,$cnum,'/syllabus/loncapa.html'); &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.externalsyllabus'); &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.minimalsyllabus'); $storehash{'externalsyllabus'} = ''; $storehash{'minimalsyllabus'} = ''; $putres = &Apache::lonnet::put('environment',\%storehash,$cdom,$cnum); undef($external); undef($minimal); } } elsif ($env{'form.choice'} eq 'template') { #store what the user typed in to the template my @shown = &Apache::loncommon::get_env_multiple('form.showfield'); $syllabus->{'uploaded.fields'} = ''; if (@shown == 0) { $syllabus->{'uploaded.fields'} = 'none'; } else { foreach my $field (sort(@shown)) { if (($field eq '000_showpeople') || ($field eq '111_showrssfeeds') || ($syllabusfields->{$field})) { my ($prefix) = split(/_/,$field); $syllabus->{'uploaded.fields'} .= $prefix.','; } if ($field eq '000_showpeople') { my @hideusers = &Apache::loncommon::get_env_multiple('form.hideuser'); my @hideroles = &Apache::loncommon::get_env_multiple('form.hiderole'); my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum,1); my %personnel; foreach my $key (keys(%coursepersonnel)) { map { $personnel{$key}{$_} = 1; } split(/,/,$coursepersonnel{$key}); } %{$syllabus->{'personnel'}} = (); $syllabus->{'personnel'}{'hideuser'} = ''; $syllabus->{'personnel'}{'hiderole'} = ''; foreach my $role (@hideroles) { if (exists($personnel{$role})) { $syllabus->{'personnel'}{'hiderole'} .= $role.','; } } foreach my $item (@hideusers) { my ($role,$user) = split(/\&/,$item); if (ref($personnel{$role}) eq 'HASH') { if ($personnel{$role}{$user}) { $syllabus->{'personnel'}{'hideuser'} .= $item.','; } } } $syllabus->{'personnel'}{'hideuser'} =~ s/,$//; $syllabus->{'personnel'}{'hiderole'} =~ s/,$//; } } $syllabus->{'uploaded.fields'} =~ s/,$//; } foreach my $syl_field (keys(%{$syllabusfields})) { my $field=$env{'form.'.$syl_field}; chomp($field); my $gateway = Apache::lonhtmlgateway->new(); $field = $gateway->process_incoming_html($field,1); #here it will be stored $syllabus->{$syl_field}=$field; if ($syl_field eq 'lll_includeurl') { # clean up included URLs my $field=''; foreach my $value (split(/\n/,$syllabus->{$syl_field})) { my $url=$value; # get rid of leading and trailing spaces $url=~s/^\s+//; $url=~s/\s+$//; if ($url=~m|^https?\://([^/]+)/(.+)$|) { my $host = $1; my $remainder=$2; # remove the hostname from internal URLs my $hostname = &Apache::lonnet::hostname($host); my %all_hostnames = &Apache::lonnet::all_hostnames(); foreach my $possible_host (keys(%all_hostnames)) { if ($possible_host =~ /\Q$hostname\E/i) { $url=$remainder; } } } # norm internal URLs unless ($url=~/^https?\:/) { $url=&Apache::lonnet::clutter($url); } # re-assemble field if ($url) { $field.=$url."\n"; } } $syllabus->{$syl_field}=$field; } } my $now = time; $syllabus->{'uploaded.domain'}=$env{'user.domain'}; $syllabus->{'uploaded.name'}=$env{'user.name'}; $syllabus->{'uploaded.lastmodified'} = $now; $putres = &Apache::lonnet::put('syllabus',$syllabus,$cdom,$cnum); if ($putres eq 'ok') { ($uploaded,$minimal,$external) = &update_syllabus_env($cdom,$cnum,$courseenv,$env{'form.choice'},$uploaded, $minimal,$external); $output = '
'. &Apache::lonhtmlcommon::confirm_success(&mt('Template saved.')). '
'; } else { $output = '
'. &mt('An error occurred storing the template: [_1]',$putres). '
'; } } elsif ($env{'form.choice'} eq 'url') { if ($env{'form.externalsyllabus'} =~ m{^https?://}) { if ($env{'form.externalsyllabus'} eq $external) { $output = '
'. &mt('External URL unchanged.'). '
'; ($uploaded,$minimal,$external) = &update_syllabus_env($cdom,$cnum,$courseenv,$env{'form.choice'},$uploaded, $minimal,$external); } else { $external=$env{'form.externalsyllabus'}; $external =~ s/(`)//g; $putres = &Apache::lonnet::put('environment',{externalsyllabus=>$external}, $cdom,$cnum); if ($putres eq 'ok') { &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.externalsyllabus' => $external}); $output = '
'. &Apache::lonhtmlcommon::confirm_success(&mt('External URL saved.')). '
'; ($uploaded,$minimal,$external) = &update_syllabus_env($cdom,$cnum,$courseenv,$env{'form.choice'},$uploaded, $minimal,$external); } else { $output = '
'. &mt('An error occurred storing the external URL: [_1]',$putres). '
'; } $is_ext = $external; } } else { $output = '
'. &mt('External URL not saved -- invalid URL.'). '
'; } } elsif (($env{'form.choice'} eq 'file') || ($env{'form.choice'} eq 'minimal')) { # Process file upload - phase one - upload and parse primary file. my ($upload_result,$uploadphase,$url,$needlink,$error,$errormsg); if ($env{'form.choice'} eq 'file') { if ($env{'form.syllabusfile.filename'}) { my %allfiles = (); my %codebase = (); ($url,$needlink) = &process_upload(\$output,$cnum,$cdom, \%allfiles,\%codebase); } else { $output = '
'. &mt('No file uploaded'). '
'; } } elsif ($env{'form.choice'} eq 'minimal') { $url = "/uploaded/$cdom/$cnum/portfolio/syllabus/loncapa.html"; my $filecontents=&Apache::lonnet::getfile(&Apache::lonnet::filelocation("",$url)); if ($filecontents eq -1) { $url = &default_minimal_syllabus($cnum,$cdom); } } if ($url =~ m{^/uploaded/\Q$cdom\E/\Q$cnum\E.*/[^/]+$}) { my $exturl = &home_http_host($cdom,$cnum); if ($exturl) { $exturl .= $url; } my %storehash; if ($env{'form.choice'} eq 'minimal') { $storehash{'minimalsyllabus'} = $url; } else { $storehash{'uploadedsyllabus'} = $url; } if ($exturl) { $storehash{'externalsyllabus'} = $exturl; if ($exturl =~ /\.(html?|txt|js|css)$/) { $exturl .= '?inhibitmenu=yes'; } } else { $storehash{'externalsyllabus'} = '', } $putres = &Apache::lonnet::put('environment',\%storehash,$cdom,$cnum); if ($putres eq 'ok') { &Apache::lonnet::make_public_indefinitely($url); foreach my $key (keys(%storehash)) { &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash{$key}}); } if ($env{'form.choice'} eq 'minimal') { $minimal = $url; } else { $uploaded = $url; } if ($needlink) { $output .= &return_to_editor($cdom,$cnum); $earlyout = 1; } ($uploaded,$minimal,$external) = &update_syllabus_env($cdom,$cnum,$courseenv,$env{'form.choice'},$uploaded, $minimal,$external); } else { $error = 1; $errormsg = $putres; } } else { $error = 1; } if ($error) { $output = '
'; if ($env{'form.choice'} eq 'minimal') { $output = &mt('An error occurred creating the minimal template file [_1]',$errormsg); } else { $output = &mt('An error occurred storing the uploaded file [_1]',$errormsg); } $output .= '
'; } } elsif ($env{'form.phase'} eq 'upload_embedded') { # Process file upload - phase two - upload embedded objects my $uploadphase = 'check_embedded'; my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"'); my $state = &embedded_form_elems($uploadphase,$primaryurl); my $url_root = '/uploaded/'.$cdom.'/'.$cnum; my $actionurl = "/public/$cdom/$cnum/syllabus"; my ($result,$flag,$numpathchgs) = &Apache::loncommon::upload_embedded('syllabus','portfolio/syllabus', $cnum,$cdom,'/userfiles',$url_root,undef,undef,undef,$state, $actionurl); unless ($numpathchgs) { my $modres = &Apache::loncommon::modify_html_refs('syllabus','portfolio/syllabus', $cnum,$cdom, '/userfiles',$env{'form.primaryurl'}); $result .= $modres; } $output = $result.&return_to_editor($cdom,$cnum); $earlyout = 1; } elsif ($env{'form.phase'} eq 'check_embedded') { # Process file upload - phase three - modify references in HTML file my $uploadphase = 'modified_orightml'; my $result = &Apache::loncommon::modify_html_refs('syllabus','portfolio/syllabus', $cnum,$cdom, '/userfiles',$env{'form.primaryurl'}); $output = $result.&return_to_editor($cdom,$cnum); $earlyout = 1; } if ($putres eq 'ok') { if ((($is_ext) && ($is_ext ne $was_ext)) || ($was_ext)) { my $chome = &Apache::lonnet::homeserver($cnum,$cdom); unless ($chome eq 'no_host') { my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.'); if (ref($crsinfo{$cdom.'_'.$cnum}) eq 'HASH') { if ($external =~ m{^http://}) { $crsinfo{$cdom.'_'.$cnum}{'extsyllplain'} = 1; } elsif ($crsinfo{$cdom.'_'.$cnum}{'extsyllplain'}) { delete($crsinfo{$cdom.'_'.$cnum}{'extsyllplain'}); } &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime'); } } } } return ($earlyout,$uploaded,$external,$minimal,$output); } sub default_minimal_syllabus { my ($cnum,$cdom) = @_; my $title; if ($env{'form.syllabustitle'}) { $title = $env{'form.syllabustitle'}; $title =~ s{`}{}g; $title=~s/^\s+//; $title=~s/\s+$//; } if ($title eq '') { $title = &mt('Syllabus'); } my $initialtext = &mt('Replace with your own content.'); my $newhtml = < $title

$title

$initialtext END $env{'form.output'}=$newhtml; return &Apache::lonnet::finishuserfileupload($cnum,$cdom,'output', 'portfolio/syllabus/loncapa.html'); } sub update_syllabus_env { my ($cdom,$cnum,$courseenv,$saved,$uploaded,$minimal,$external) = @_; return ($uploaded,$minimal,$external) unless(ref($courseenv) eq 'HASH'); my $now = time; my (@envkeys,%storehash); if ($saved eq 'template') { if ($uploaded || $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) { push(@envkeys,'uploaded'); } if ($minimal || $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'}) { push(@envkeys,'minimal'); } if ($external || $env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) { push(@envkeys,'external'); } $storehash{'updatedsyllabus'} = $now; &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.updatedsyllabus' => $now }); } elsif ($saved eq 'url') { my $prefix = &home_http_host($cdom,$cnum); if ($external =~ m{^\Q$prefix/uploaded/$cdom/$cnum/portfolio/syllabus/\E(.+)$}) { my $file = $1; if ($file eq 'loncapa.html') { if ($uploaded || $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) { push(@envkeys,'uploaded'); } } elsif ($minimal || $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'}) { push(@envkeys,'minimal'); } } else { if ($uploaded || $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) { push(@envkeys,'uploaded'); } if ($minimal || $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'}) { push(@envkeys,'minimal'); } } } elsif ($saved eq 'file') { if ($minimal || $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'}) { push(@envkeys,'minimal'); } } elsif ($saved eq 'minimal') { if ($uploaded || $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) { push(@envkeys,'uploaded'); } } if (@envkeys > 0) { foreach my $item (@envkeys) { my $key = $item.'syllabus'; if ($courseenv->{$key} ne '') { &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.'.$key); if ($item eq 'minimal') { &update_access_permissions($cdom,$cnum,'/syllabus/loncapa.html'); } elsif ($item eq 'uploaded') { if ($courseenv->{$key} =~ m{^\Q/uploaded/$cdom/$cnum/portfolio\E(/syllabus/.+)$}) { my $filename = $1; &update_access_permissions($cdom,$cnum,$filename); } } $storehash{$key} = ''; } elsif ($env{'course.'.$env{'request.course.id'}.'.'.$key} ne '') { &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.'.$key); } if ($item eq 'uploaded') { undef($uploaded); } if ($item eq 'external') { undef($external); } if ($item eq 'minimal') { undef($minimal); } } } if (keys(%storehash) > 0) { &Apache::lonnet::put('environment',\%storehash,$cdom,$cnum); } return ($uploaded,$minimal,$external); } sub update_access_permissions { my ($cdom,$cnum,$file_name) = @_; my $current_permissions = &Apache::lonnet::get_portfile_permissions($cdom,$cnum); my %access_controls = &Apache::lonnet::get_access_controls($current_permissions,'',$file_name); if (keys(%access_controls) > 0) { my %changes; foreach my $key (keys(%{$access_controls{$file_name}})) { $changes{'delete'}{$key} = 1; } if (keys(%changes) > 0) { my ($outcome,$deloutcome,$new_values,$translation) = &Apache::lonnet::modify_access_controls($file_name,\%changes, $cdom,$cnum); } } return; } sub home_http_host { my ($cdom,$cnum) = @_; my $home=&Apache::lonnet::homeserver($cnum,$cdom); if ($home ne 'no_host') { my $hostname = &Apache::lonnet::hostname($home); my $protocol = $Apache::lonnet::protocol{$home}; $protocol = 'http' if ($protocol ne 'https'); return $protocol.'://'.$hostname; } return; } sub process_upload { my ($upload_output,$cnum,$cdom,$allfiles,$codebase) = @_; my ($parseaction,$showupload,$mimetype); my $dest = 'portfolio/syllabus'; if ($env{'form.parserflag'}) { $parseaction = 'parse'; } my $url=&Apache::lonnet::userfileupload('syllabusfile','syllabus',$dest, $parseaction,$allfiles, $codebase,undef,undef,undef,undef, undef,undef,\$mimetype); if ($url =~ m{^/uploaded/\Q$cdom\E/\Q$cnum\E.*/([^/]+)$}) { my $stored = $1; $showupload = '

'.&mt('Uploaded [_1]', ''.$stored.''). '

'; } else { my ($filename) = ($env{'form.syllabusfile.filename'} =~ m{([^/]+)$}); $$upload_output = '
'. &mt('Unable to save file [_1].', ''.$filename.''). '
'; return (); } my $needlink; if (($parseaction eq 'parse') && ($mimetype eq 'text/html')) { $$upload_output = $showupload; my $total_embedded = scalar(keys(%{$allfiles})); if ($total_embedded > 0) { my $uploadphase = 'upload_embedded'; my $primaryurl = &HTML::Entities::encode($url,'<>&"'); my $state = &embedded_form_elems($uploadphase,$primaryurl); my $actionurl = "/public/$cdom/$cnum/syllabus"; my ($embedded,$num,$numpathchanges,$existing); ($embedded,$num,$numpathchanges,$existing) = &Apache::loncommon::ask_for_embedded_content($actionurl,$state, $allfiles,$codebase, {'error_on_invalid_names' => 1, 'ignore_remote_references' => 1,}); if ($embedded) { $needlink = 1; if ($num) { $$upload_output .= '

'.&mt('This file contains embedded multimedia objects, which need to be uploaded.').'

'.$embedded; } elsif ($numpathchanges) { $$upload_output .= $embedded; } else { $$upload_output .= $embedded; &Apache::loncommon::modify_html_refs('syllabus','portfolio/syllabus', $cnum,$cdom,'/userfiles',$url); } } else { $$upload_output .= &mt('Embedded item(s) already present, so no additional upload(s) required').'
'; &Apache::loncommon::modify_html_refs('syllabus','portfolio/syllabus', $cnum,$cdom,'/userfiles',$url); } } else { $$upload_output .= &mt('No embedded items identified').'
'; } $$upload_output = '
'.$$upload_output.'
'; } return ($url,$needlink); } sub embedded_form_elems { my ($phase,$primaryurl) = @_; return < STATE } sub return_to_editor { my ($cdom,$cnum) = @_; my $actionurl = "/public/$cdom/$cnum/syllabus"; return '

'. ''."\n". ''.&mt('Return to Editor'). '

'; } sub editfile_button { my ($url,$context,$editable) = @_; my $edittext=&mt('Edit'); my $deltext=&mt('Delete'); my $output; if ($editable) { $output = '    '; } $output .= ' '; return $output; } sub editbutton_js { my %js_lt = &Apache::lonlocal::texthash( min => 'Are you sure you want to delete the contents of the syllabus template?', file => 'Are you sure you want to delete the uploaded syllabus file?', noundo => 'This action cannot be reversed.' ); &js_escape(\%js_lt); return < // ENDJS } sub redirect_to_http { my ($r) = @_; &Apache::loncommon::content_type($r,'text/html'); &Apache::loncommon::no_cache($r); $r->send_http_header; my $url = 'http://'.$r->hostname().$r->uri().'?usehttp=1'; $r->print(&Apache::loncommon::start_page(undef,undef, {'redirect' => [0,$url],}). &Apache::loncommon::end_page()); return; } 1; __END__ 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.