--- loncom/interface/loncommon.pm 2006/12/06 11:36:52 1.488 +++ loncom/interface/loncommon.pm 2007/02/28 21:45:43 1.509 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.488 2006/12/06 11:36:52 foxr Exp $ +# $Id: loncommon.pm,v 1.509 2007/02/28 21:45:43 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -59,6 +59,7 @@ use Apache::lonnet; use GDBM_File; use POSIX qw(strftime mktime); use Apache::lonmenu(); +use Apache::lonenc(); use Apache::lonlocal; use HTML::Entities; use Apache::lonhtmlcommon(); @@ -515,8 +516,8 @@ function setSect(sectionlist) { sub selectcourse_link { my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype)=@_; - return "".&mt('Select [_1]',$selecttype).""; + return "".&mt('Select Course').""; } sub check_uncheck_jscript { @@ -1314,11 +1315,11 @@ Returns a string containing a e Args: $name - name of the element - $value - sclara or array ref of values that should already be selected + $value - scalar or array ref of values that should already be selected $size - number of rows long the select element is $hash - the elements should be 'option' => 'shown text' (shown text should already have been &mt()) - $order - (optional) array ref of the order to show the elments in + $order - (optional) array ref of the order to show the elements in =cut @@ -1334,8 +1335,16 @@ sub multiple_select_form { } } $output.="\n"; - my @order = ref($order) ? @$order - : sort(keys(%$hash)); + my @order; + if (ref($order) eq 'ARRAY') { + @order = @{$order}; + } else { + @order = sort(keys(%$hash)); + } + if (exists($$hash{'select_form_order'})) { + @order = @{$$hash{'select_form_order'}}; + } + foreach my $key (@order) { $output.='&').'" '; $output.='selected="selected" ' if ($selected{$key}); @@ -2258,6 +2267,19 @@ sub track_student_link { &help_open_topic('View_recent_activity'); } +# ===================================================== Display a student photo + + +sub student_image_tag { + my ($domain,$user)=@_; + my $imgsrc=&Apache::lonnet::studentphoto($domain,$user,'jpg'); + if (($imgsrc) && ($imgsrc ne '/adm/lonKaputt/lonlogo_broken.gif')) { + return ''; + } else { + return ''; + } +} + =pod =back @@ -2690,7 +2712,9 @@ sub get_student_answers { } $moreenv{'grade_target'}='answer'; %moreenv=(%form,%moreenv); - my $userview=&Apache::lonnet::ssi('/res/'.$feedurl,%moreenv); + $feedurl = &Apache::lonnet::clutter($feedurl); + &Apache::lonenc::check_encrypt(\$feedurl); + my $userview=&Apache::lonnet::ssi($feedurl,%moreenv); return $userview; } @@ -2850,7 +2874,7 @@ sub findallcourses { $cnum = $cnumpart; ($sec,$role) = split(/_/,$secpart); $realsec = $sec; - } + } $courses{$cdom.'_'.$cnum}{$sec} = $trole.'/'.$cdom.'/'.$cnum.'/'.$realsec; } } else { @@ -2885,15 +2909,50 @@ sub findallcourses { sub blockcheck { my ($setters,$activity,$uname,$udom) = @_; - # Retrieve active course roles - course coordinator, instructor, exam proctor, ta, student or custom role. - my %live_courses = &findallcourses(undef,$uname,$udom); + if (!defined($udom)) { + $udom = $env{'user.domain'}; + } + if (!defined($uname)) { + $uname = $env{'user.name'}; + } + + # If uname and udom are for a course, check for blocks in the course. - # Retrieve blocking times and identity of blocker for active courses - # of specified user, unless user has 'evb' privilege. + if (&Apache::lonnet::is_course($udom,$uname)) { + my %records = &Apache::lonnet::dump('comm_block',$udom,$uname); + my ($startblock,$endblock)=&get_blocks($setters,$activity,$udom,$uname); + return ($startblock,$endblock); + } my $startblock = 0; my $endblock = 0; + my %live_courses = &findallcourses(undef,$uname,$udom); + + # If uname is for a user, and activity is course-specific, i.e., + # boards, chat or groups, check for blocking in current course only. + + if (($activity eq 'boards' || $activity eq 'chat' || + $activity eq 'groups') && ($env{'request.course.id'})) { + foreach my $key (keys(%live_courses)) { + if ($key ne $env{'request.course.id'}) { + delete($live_courses{$key}); + } + } + } + + my $otheruser = 0; + my %own_courses; + if ((($uname ne $env{'user.name'})) || ($udom ne $env{'user.domain'})) { + # Resource belongs to user other than current user. + $otheruser = 1; + # Gather courses for current user + %own_courses = + &findallcourses(undef,$env{'user.name'},$env{'user.domain'}); + } + + # Gather active course roles - course coordinator, instructor, + # exam proctor, ta, student, or custom role. foreach my $course (keys(%live_courses)) { my ($cdom,$cnum); @@ -2901,17 +2960,36 @@ sub blockcheck { $cdom = $env{'course.'.$course.'.domain'}; $cnum = $env{'course.'.$course.'.num'}; } else { - ($cdom,$cnum) = split(/_/,$course); + ($cdom,$cnum) = split(/_/,$course); } my $no_ownblock = 0; my $no_userblock = 0; + if ($otheruser) { + # Check if current user has 'evb' priv for this + if (defined($own_courses{$course})) { + foreach my $sec (keys(%{$own_courses{$course}})) { + my $checkrole = 'cm./'.$cdom.'/'.$cnum; + if ($sec ne 'none') { + $checkrole .= '/'.$sec; + } + if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) { + $no_ownblock = 1; + last; + } + } + } + # if they have 'evb' priv and are currently not playing student + next if (($no_ownblock) && + ($env{'request.role'} !~ m{^st\./$cdom/$cnum})); + } foreach my $sec (keys(%{$live_courses{$course}})) { my $checkrole = 'cm./'.$cdom.'/'.$cnum; if ($sec ne 'none') { $checkrole .= '/'.$sec; } - if ((defined($uname) && ($uname ne $env{'user.name'})) || - (defined($udom) && ($udom ne $env{'user.domain'}))) { + if ($otheruser) { + # Resource belongs to user other than current user. + # Assemble privs for that user, and check for 'evb' priv. my ($trole,$tdom,$tnum,$tsec); my $entry = $live_courses{$course}{$sec}; if ($entry =~ /^cr/) { @@ -2942,7 +3020,9 @@ sub blockcheck { last; } } - } else { + } else { + # Resource belongs to current user + # Check for 'evb' priv via lonnet::allowed(). if (&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) { $no_ownblock = 1; last; @@ -2951,26 +3031,47 @@ sub blockcheck { } # if they have the evb priv and are currently not playing student next if (($no_ownblock) && - ($env{'request.role'} !~ m{^st\./$cdom/$cnum})); + ($env{'request.role'} !~ m{^st\./\Q$cdom\E/\Q$cnum\E})); next if ($no_userblock); - $setters->{$course} = {}; - $setters->{$course}{'staff'} = []; - $setters->{$course}{'times'} = []; - my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum); - foreach my $record (keys(%records)) { - my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/); - if ($start <= time && $end >= time) { - my ($staff_name,$staff_dom,$title,$blocks) = - &parse_block_record($records{$record}); - if ($blocks->{$activity} eq 'on') { - push(@{$$setters{$course}{'staff'}}, [$staff_name,$staff_dom]); push(@{$$setters{$course}{'times'}}, [$start,$end]); - if ( ($startblock == 0) || ($startblock > $1) ) { - $startblock = $1; - } - if ( ($endblock == 0) || ($endblock < $2) ) { - $endblock = $2; - } + # Retrieve blocking times and identity of blocker for course + # of specified user, unless user has 'evb' privilege. + + my ($start,$end)=&get_blocks($setters,$activity,$cdom,$cnum); + if (($start != 0) && + (($startblock == 0) || ($startblock > $start))) { + $startblock = $start; + } + if (($end != 0) && + (($endblock == 0) || ($endblock < $end))) { + $endblock = $end; + } + } + return ($startblock,$endblock); +} + +sub get_blocks { + my ($setters,$activity,$cdom,$cnum) = @_; + my $startblock = 0; + my $endblock = 0; + my $course = $cdom.'_'.$cnum; + $setters->{$course} = {}; + $setters->{$course}{'staff'} = []; + $setters->{$course}{'times'} = []; + my %records = &Apache::lonnet::dump('comm_block',$cdom,$cnum); + foreach my $record (keys(%records)) { + my ($start,$end) = ($record =~ m/^(\d+)____(\d+)$/); + if ($start <= time && $end >= time) { + my ($staff_name,$staff_dom,$title,$blocks) = + &parse_block_record($records{$record}); + if ($blocks->{$activity} eq 'on') { + push(@{$$setters{$course}{'staff'}},[$staff_name,$staff_dom]); + push(@{$$setters{$course}{'times'}}, [$start,$end]); + if ( ($startblock == 0) || ($startblock > $start) ) { + $startblock = $start; + } + if ( ($endblock == 0) || ($endblock < $end) ) { + $endblock = $end; } } } @@ -3020,20 +3121,83 @@ sub build_block_table { my %courseinfo=&Apache::lonnet::coursedescription($course); for (my $i=0; $i<@{$$setters{$course}{staff}}; $i++) { my ($uname,$udom) = @{$$setters{$course}{staff}[$i]}; - my $fullname = &aboutmewrapper(&plainname($uname,$udom),$uname,$udom); + my $fullname = &plainname($uname,$udom); + if (defined($env{'user.name'}) && defined($env{'user.domain'}) + && $env{'user.name'} ne 'public' + && $env{'user.domain'} ne 'public') { + $fullname = &aboutmewrapper($fullname,$uname,$udom); + } my ($openblock,$closeblock) = @{$$setters{$course}{times}[$i]}; $openblock = &Apache::lonlocal::locallocaltime($openblock); $closeblock= &Apache::lonlocal::locallocaltime($closeblock); $output .= &Apache::loncommon::start_data_table_row(). ''.$courseinfo{'description'}.''. ''.$openblock.' to '.$closeblock.''. - ''.$fullname.'.'. + ''.$fullname.''. &Apache::loncommon::end_data_table_row(); } } $output .= &end_data_table(); } +sub blocking_status { + my ($activity,$uname,$udom) = @_; + my %setters; + my ($blocked,$output,$ownitem,$is_course); + my ($startblock,$endblock)=&blockcheck(\%setters,$activity,$uname,$udom); + if ($startblock && $endblock) { + $blocked = 1; + if (wantarray) { + my $category; + if ($activity eq 'boards') { + $category = 'Discussion posts in this course'; + } elsif ($activity eq 'blogs') { + $category = 'Blogs'; + } elsif ($activity eq 'port') { + if (defined($uname) && defined($udom)) { + if ($uname eq $env{'user.name'} && + $udom eq $env{'user.domain'}) { + $ownitem = 1; + } + } + $is_course = &Apache::lonnet::is_course($udom,$uname); + if ($ownitem) { + $category = 'Your portfolio files'; + } elsif ($is_course) { + my $coursedesc; + foreach my $course (keys(%setters)) { + my %courseinfo = + &Apache::lonnet::coursedescription($course); + $coursedesc = $courseinfo{'description'}; + } + $category = "Group files in the course '$coursedesc'"; + } else { + $category = 'Portfolio files belonging to '; + if ($env{'user.name'} eq 'public' && + $env{'user.domain'} eq 'public') { + $category .= &plainname($uname,$udom); + } else { + $category .= &aboutmewrapper(&plainname($uname,$udom),$uname,$udom); + } + } + } elsif ($activity eq 'groups') { + $category = 'Groups in this course'; + } + my $showstart = &Apache::lonlocal::locallocaltime($startblock); + my $showend = &Apache::lonlocal::locallocaltime($endblock); + $output = ''.&mt('[_1] will be inaccessible between [_2] and [_3] because communication is being blocked.',$category,$showstart,$showend).''; + if (!($activity eq 'port' && !($ownitem) && !($is_course))) { + $output .= &build_block_table($startblock,$endblock,\%setters); + } + } + } + if (wantarray) { + return ($blocked,$output); + } else { + return $blocked; + } +} + ############################################### =pod @@ -3207,7 +3371,7 @@ sub bodytag { my ($role,$realm) = split(/\./,$env{'request.role'},2); if ($role eq 'ca') { my ($rdom,$rname) = ($realm =~ m{^/($match_domain)/($match_username)$}); - $realm = &plainname($rname,$rdom).':'.$rdom; + $realm = &plainname($rname,$rdom); } # realm if ($env{'request.course.id'}) { @@ -3503,6 +3667,7 @@ sub standard_css { my $mail_other = '#99BBBB'; my $mail_other_hover = '#669999'; my $table_header = '#DDDDDD'; + my $feedback_link_bg = '#BBBBBB'; my $border = ($env{'browser.type'} eq 'explorer') ? '0px 2px 0px 2px' : '0px 3px 0px 4px'; @@ -3684,6 +3849,18 @@ table.LC_data_table, table.LC_mail_list .LC_data_table_dense { font-size: small; } +table.LC_nested_outer { + border: 1px solid #000000; + border-collapse: separate; + border-spacing: 0px; + width: 100%; +} +table.LC_nested { + border: 0px; + border-collapse: separate; + border-spacing: 0px; + width: 100%; +} table.LC_data_table tr th, table.LC_calendar tr th, table.LC_mail_list tr th { font-weight: bold; background-color: $data_table_head; @@ -3702,36 +3879,50 @@ table.LC_data_table tr.LC_data_table_hig background-color: $data_table_darker; } table.LC_data_table tr.LC_empty_row td, -table.LC_whatsnew tr.LC_empty_row td { +table.LC_nested tr.LC_empty_row td { background-color: #FFFFFF; font-weight: bold; font-style: italic; text-align: center; padding: 8px; } -table.LC_whatsnew tr.LC_empty_row td { +table.LC_nested tr.LC_empty_row td { padding: 4ex } -table.LC_whatsnew { +table.LC_nested_outer tr th { + font-weight: bold; + background-color: $data_table_head; + font-size: smaller; + border-bottom: 1px solid #000000; } - -table.LC_whatsnew tr th, -table.LC_whatsnew tr.LC_info_row td { - background-color: #CCC; +table.LC_nested_outer tr td.LC_subheader { + background-color: $data_table_head; font-weight: bold; font-size: small; + border-bottom: 1px solid #000000; text-align: right; } -table.LC_whatsnew tr td { - background-color: #FFF; +table.LC_nested tr.LC_info_row td { + background-color: #CCC; + font-weight: bold; font-size: small; - text-align: right; + text-align: center; } -table.LC_whatsnew tr td.LC_first_item { +table.LC_nested tr.LC_info_row td.LC_left_item { text-align: left; } +table.LC_nested td { + background-color: #FFF; + font-size: small; +} +table.LC_nested_outer tr th.LC_right_item, +table.LC_nested tr.LC_info_row td.LC_right_item, +table.LC_nested tr.LC_odd_row td.LC_right_item, +table.LC_nested tr td.LC_right_item { + text-align: right; +} -table.LC_whatsnew tr.LC_odd_row td { +table.LC_nested tr.LC_odd_row td { background-color: #EEE; } @@ -3790,6 +3981,11 @@ table.LC_mail_list tr.LC_mail_other { table.LC_mail_list tr.LC_mail_other:hover { background-color: $mail_other_hover; } +table.LC_mail_list tr.LC_mail_even { +} +table.LC_mail_list tr.LC_mail_odd { +} + table#LC_portfolio_actions { width: auto; @@ -4034,6 +4230,13 @@ table.LC_descriptive_input td.LC_descrip text-align: right; font-weight: bold; } +table.LC_feedback_link { + background: $feedback_link_bg; +} +span.LC_feedback_link { + background: $feedback_link_bg; + font-size: larger; +} END } @@ -4326,6 +4529,11 @@ Inputs: $args - additional optio a html attribute frameset -> if true will start with a rather than + dicsussion -> if true will get discussion from + lonxml::xmlend + (you can pass the target and parser arguments + through optional 'target' and 'parser' args + to this routine) =cut @@ -4784,7 +4992,7 @@ sub get_course_users { $usec = 'none'; } if ($uname ne '' && $udom ne '') { - if ($end < $now) { + if ($end > 0 && $end < $now) { $status = 'previous'; } elsif ($start > $now) { $status = 'future'; @@ -5226,9 +5434,9 @@ sub record_sep { } else { my @allfields; if ($env{'form.upfiletype'} eq 'semisv') { - @allfields=split(/;/,$record); + @allfields=split(/;/,$record,-1); } else { - @allfields=split(/\,/,$record); + @allfields=split(/\,/,$record,-1); } my $i=0; my $j; @@ -5922,16 +6130,19 @@ Returns: both routines return nothing ####################################################### ####################################################### sub store_course_settings { + return &store_settings($env{'request.course.id'},@_); +} + +sub store_settings { # save to the environment # appenv the same items, just to be safe - my $courseid = $env{'request.course.id'}; my $udom = $env{'user.domain'}; my $uname = $env{'user.name'}; - my ($prefix,$Settings) = @_; + my ($context,$prefix,$Settings) = @_; my %SaveHash; my %AppHash; while (my ($setting,$type) = each(%$Settings)) { - my $basename = join('.','internal',$courseid,$prefix,$setting); + my $basename = join('.','internal',$context,$prefix,$setting); my $envname = 'environment.'.$basename; if (exists($env{'form.'.$setting})) { # Save this value away @@ -5971,11 +6182,14 @@ sub store_course_settings { } sub restore_course_settings { - my $courseid = $env{'request.course.id'}; - my ($prefix,$Settings) = @_; + return &restore_settings($env{'request.course.id'},@_); +} + +sub restore_settings { + my ($context,$prefix,$Settings) = @_; while (my ($setting,$type) = each(%$Settings)) { next if (exists($env{'form.'.$setting})); - my $envname = 'environment.internal.'.$courseid.'.'.$prefix. + my $envname = 'environment.internal.'.$context.'.'.$prefix. '.'.$setting; if (exists($env{$envname})) { if ($type eq 'scalar') { @@ -6390,7 +6604,7 @@ sub group_term { sub icon { my ($file)=@_; - my $curfext = (split(/\./,$file))[-1]; + my $curfext = lc((split(/\./,$file))[-1]); my $iconname=$Apache::lonnet::perlvar{'lonIconsURL'}.'/unknown.gif'; my $embstyle = &Apache::loncommon::fileembstyle($curfext); if (!(!defined($embstyle) || $embstyle eq 'unk' || $embstyle eq 'hdn')) {