--- loncom/interface/loncommon.pm 2005/11/08 02:12:24 1.282 +++ loncom/interface/loncommon.pm 2005/11/22 00:01:41 1.298 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.282 2005/11/08 02:12:24 albertel Exp $ +# $Id: loncommon.pm,v 1.298 2005/11/22 00:01:41 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -380,7 +380,7 @@ sub coursebrowser_javascript { return (< var stdeditbrowser; - function opencrsbrowser(formname,uname,udom,desc,extra_element) { + function opencrsbrowser(formname,uname,udom,desc,extra_element,multflag) { var url = '/adm/pickcourse?'; var filter; if (filter != null) { @@ -403,6 +403,9 @@ sub coursebrowser_javascript { url += '&domainfilter='+extra_element; } } + if (multflag !=null && multflag != '') { + url += '&multiple='+multflag; + } var title = 'Course_Browser'; var options = 'scrollbars=1,resizable=1,menubar=0'; options += ',width=700,height=600'; @@ -414,9 +417,9 @@ ENDSTDBRW } sub selectcourse_link { - my ($form,$unameele,$udomele,$desc,$extra_element)=@_; + my ($form,$unameele,$udomele,$desc,$extra_element,$multflag)=@_; return "".&mt('Select Course').""; + '","'.$udomele.'","'.$desc.'","'.$extra_element.'","'.$multflag.'");'."'>".&mt('Select Course').""; } sub check_uncheck_jscript { @@ -1149,7 +1152,7 @@ sub domain_select { } &get_domains; if ($multiple) { $domains{''}=&mt('Any domain'); - return &multiple_select_form($name,$value,4,%domains); + return &multiple_select_form($name,$value,4,\%domains); } else { return &select_form($name,$value,%domains); } @@ -1159,7 +1162,7 @@ sub domain_select { =pod -=item * multiple_select_form($name,$value,$size,%hash) +=item * multiple_select_form($name,$value,$size,$hash,$order) Returns a string containing a element $value - sclara 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' + $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 + =cut #------------------------------------------- sub multiple_select_form { - my ($name,$value,$size,%hash)=@_; + my ($name,$value,$size,$hash,$order)=@_; my %selected = map { $_ => 1 } ref($value)?@{$value}:($value); my $output=''; if (! defined($size)) { $size = 4; - if (scalar(keys(%hash))<4) { - $size = scalar(keys(%hash)); + if (scalar(keys(%$hash))<4) { + $size = scalar(keys(%$hash)); } } $output.="\n\n"; return $output; @@ -1913,12 +1920,11 @@ if $first is set to 'lastname' then it r =cut + ############################################################### sub plainname { my ($uname,$udom,$first)=@_; - my %names=&Apache::lonnet::get('environment', - ['firstname','middlename','lastname','generation'], - $udom,$uname); + my %names=&getnames($uname,$udom); my $name=&Apache::lonnet::format_name($names{'firstname'}, $names{'middlename'}, $names{'lastname'}, @@ -1949,19 +1955,7 @@ if the user does not sub nickname { my ($uname,$udom)=@_; - my %names; - if ($uname eq $env{'user.name'} && - $udom eq $env{'user.domain'}) { - %names=('nickname' => $env{'environment.nickname'} , - 'firstname' => $env{'environment.firstname'} , - 'middlename' => $env{'environment.middlename'}, - 'lastname' => $env{'environment.lastname'} , - 'generation' => $env{'environment.generation'}); - } else { - %names=&Apache::lonnet::get('environment', - ['nickname','firstname','middlename', - 'lastname','generation'],$udom,$uname); - } + my %names=&getnames($uname,$udom); my $name=$names{'nickname'}; if ($name) { $name='"'.$name.'"'; @@ -1974,6 +1968,20 @@ sub nickname { return $name; } +sub getnames { + my ($uname,$udom)=@_; + my $id=$uname.':'.$udom; + my ($names,$cached)=&Apache::lonnet::is_cached_new('namescache',$id); + if ($cached) { + return %{$names}; + } else { + my %loadnames=&Apache::lonnet::get('environment', + ['firstname','middlename','lastname','generation','nickname'], + $udom,$uname); + &Apache::lonnet::do_cache_new('namescache',$id,\%loadnames); + return %loadnames; + } +} # ------------------------------------------------------------------ Screenname @@ -2529,7 +2537,7 @@ sub pgrdlink { Inputs: $text $uname $udom $symb $target Returns: A link to parmset.pm such as to see the PPRM view of a -student andn resource +student and a specific resource =cut @@ -2770,6 +2778,10 @@ sub bodytag { @@ -3072,6 +3084,138 @@ sub get_sections { } ############################################### + +=pod + +=item coursegroups + +Retrieve information about groups in a course, + +Input: +1. Reference to hash to populate with group information. +2. Optional course domain +3. Optional course number +4. Optional group name + +Course domain and number will be taken from user's +environment if not supplied. Optional group name will' +be passed to lonnet::get_coursegroups() as a regexp to +use in the call to the dump function. + +Output +Returns number of groups in the course (subject to the +optional group name filter). + +Side effects: +Populates the referenced curr_groups hash, with key, +value pairs. Keys are group names, corresponding values +are scalars containing group information in XML. This +can be sent to &get_group_settings() to be parsed. + +=cut + +############################################### + +sub coursegroups { + my ($curr_groups,$cdom,$cnum,$group) = @_; + my $numgroups; + if (!defined($cdom) || !defined($cnum)) { + my $cid = $env{'request.course.id'}; + $cdom = $env{'course.'.$cid.'.domain'}; + $cnum = $env{'course.'.$cid.'.num'}; + } + %{$curr_groups} = &Apache::lonnet::get_coursegroups($cdom,$cnum,$group); + my ($tmp) = keys(%{$curr_groups}); + if ($tmp=~/^error:/) { + unless ($tmp eq 'error: 2 tie(GDBM) Failed while attempting dump') { + &logthis('Error retrieving groups: '.$tmp.' in '.$cnum.':'. + $cdom); + } + $numgroups = 0; + } else { + $numgroups = keys(%{$curr_groups}); + } + return $numgroups; +} + +############################################### + +=pod + +=item get_group_settings + +Uses TokeParser to extract group information from the +XML used to describe course groups. + +Input: +Scalar containing XML - as retrieved from &coursegroups(). + +Output: +Hash containing group information as key=values for (a), and +hash of hashes for (b) + +Keys (in two categories): +(a) groupname, creator, creation, modified, startdate,enddate. +Corresponding values are name of the group, creator of the group +(username:domain), UNIX time for date group was created, and +settings were last modified, and default start and end access +times for group members. + +(b) functions returned in hash of hashes. +Outer hash key is functions. +Inner hash keys are chat,discussion,email,files,homepage,roster. +Corresponding values are either on or off, depending on +whther this type of functionality is available for the group. + +=cut + +############################################### + +sub get_group_settings { + my ($groupinfo)=@_; + my $parser=HTML::TokeParser->new(\$groupinfo); + my $token; + my $tool = ''; + my %content=(); + while ($token=$parser->get_token) { + if ($token->[0] eq 'S') { + my $entry=$token->[1]; + if ($entry eq 'functions') { + %{$content{$entry}} = (); + $tool = $entry; + } else { + my $value=$parser->get_text('/'.$entry); + if ($entry eq 'name') { + if ($tool eq 'functions') { + my $function = $token->[2]{id}; + $content{$tool}{$function} = $value; + } + } elsif ($entry eq 'groupname') { + $content{$entry}=&Apache::lonnet::unescape($value); + } else { + $content{$entry}=$value; + } + } + } elsif ($token->[0] eq 'E') { + if ($token->[1] eq 'functions') { + $tool = ''; + } + } + } + return %content; +} + +sub check_group_access { + my ($group) = @_; + my $access = 1; + my $now = time; + my ($start,$end) = split(/\./,$env{'user.role.gr/'.$env{'request.course,id'}.'/'.$group}); + if (($end!=0) && ($end<$now)) { $access = 0; } + if (($start!=0) && ($start>$now)) { $access=0; } + return $access; +} + +############################################### =pod @@ -3086,64 +3230,108 @@ Incoming parameters: 3. access status: users must have - either active, previous, future, or all. 4. reference to array of permissible roles -5. reference to results object (hash of hashes). +5. reference to array of section restrictions (optional) +6. reference to results object (hash of hashes). +7. reference to optional userdata hash Keys of top level hash are roles. Keys of inner hashes are username:domain, with values set to access type. - +Optional userdata hash returns an array with arguments in the +same order as loncoursedata::get_classlist() for student data. + +Entries for end, start, section and status are blank because +of the possibility of multiple values for non-student roles. + =cut ############################################### sub get_course_users { - my ($cdom,$cnum,$types,$roles,$users) = @_; - if (grep/^st$/,@{$roles}) { - my $statusidx = &Apache::loncoursedata::CL_STATUS(); - my $startidx = &Apache::loncoursedata::CL_START(); - my $endidx = &Apache::loncoursedata::CL_END(); + my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_; + my %idx = (); + + $idx{udom} = &Apache::loncoursedata::CL_SDOM(); + $idx{uname} = &Apache::loncoursedata::CL_SNAME(); + $idx{end} = &Apache::loncoursedata::CL_END(); + $idx{start} = &Apache::loncoursedata::CL_START(); + $idx{id} = &Apache::loncoursedata::CL_ID(); + $idx{section} = &Apache::loncoursedata::CL_SECTION(); + $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME(); + $idx{status} = &Apache::loncoursedata::CL_STATUS(); + + if (grep(/^st$/,@{$roles})) { my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist($cdom,$cnum); my $now = time; foreach my $student (keys(%{$classlist})) { + my $match = 0; + if ((ref($sections) eq 'ARRAY') && (@{$sections} > 0)) { + unless(grep(/^\Q$$classlist{$student}[$idx{section}]\E$/, + @{$sections})) { + next; + } + } if (defined($$types{'active'})) { - if ($$classlist{$student}[$statusidx] eq 'Active') { + if ($$classlist{$student}[$idx{status}] eq 'Active') { push(@{$$users{st}{$student}},'active'); + $match = 1; } } if (defined($$types{'previous'})) { - if ($$classlist{$student}[$endidx] <= $now) { + if ($$classlist{$student}[$idx{end}] <= $now) { push(@{$$users{st}{$student}},'previous'); + $match = 1; } } if (defined($$types{'future'})) { - if (($$classlist{$student}[$startidx] > $now) && ($$classlist{$student}[$endidx] > $now) || ($$classlist{$student}[$endidx] == 0) || ($$classlist{$student}[$endidx] eq '')) { + if (($$classlist{$student}[$idx{start}] > $now) && ($$classlist{$student}[$idx{end}] > $now) || ($$classlist{$student}[$idx{end}] == 0) || ($$classlist{$student}[$idx{end}] eq '')) { push(@{$$users{st}{$student}},'future'); + $match = 1; } } + if ($match && defined($userdata)) { + $$userdata{$student} = $$classlist{$student}; + } } } if ((@{$roles} > 0) && (@{$roles} ne "st")) { my @coursepersonnel = &Apache::lonnet::getkeys('nohist_userroles',$cdom,$cnum); foreach my $person (@coursepersonnel) { + my $match = 0; my ($role,$user) = ($person =~ /^([^:]*):([^:]+:[^:]+)/); $user =~ s/:$//; - if (($role) && (grep(/^$role$/,@{$roles}))) { - my ($uname,$udom) = split(/:/,$user); + if (($role) && (grep(/^\Q$role\E$/,@{$roles}))) { + my ($uname,$udom,$usec) = split(/:/,$user); + if ($usec ne '' && (ref($sections) eq 'ARRAY') && + @{$sections} > 0) { + unless(grep(/^\Q$usec\E$/,@{$sections})) { + next; + } + } if ($uname ne '' && $udom ne '') { my $status = &check_user_status($udom,$uname,$cdom,$cnum,$role); foreach my $type (keys(%{$types})) { if ($status eq $type) { - $$users{$role}{$user} = $type; + @{$$users{$role}{$user}} = $type; + $match = 1; } } + if ($match && defined($userdata) && + !exists($$userdata{$uname.':'.$udom})) { + &get_user_info($udom,$uname,\%idx,$userdata); + } } } } - if (grep/^ow$/,@{$roles}) { + if (grep(/^ow$/,@{$roles})) { if ((defined($cdom)) && (defined($cnum))) { my %csettings = &Apache::lonnet::get('environment',['internal.courseowner'],$cdom,$cnum); if ( defined($csettings{'internal.courseowner'}) ) { my $owner = $csettings{'internal.courseowner'}; - $$users{'ow'}{$owner.':'.$cdom} = 'any'; + @{$$users{'ow'}{$owner.':'.$cdom}} = 'any'; + if (defined($userdata) && + !exists($$userdata{$owner.':'.$cdom})) { + &get_user_info($cdom,$owner,\%idx,$userdata); + } } } } @@ -3151,7 +3339,14 @@ sub get_course_users { return; } - +sub get_user_info { + my ($udom,$uname,$idx,$userdata) = @_; + $$userdata{$uname.':'.$udom}[$$idx{fullname}] = + &plainname($uname,$udom,'lastname'); + $$userdata{$uname.':'.$udom}[$$idx{uname}] = $uname; + $$userdata{$uname.':'.$udom}[$$idx{udom}] = $udom; + return; +} ############################################### @@ -3291,6 +3486,7 @@ sub no_cache { sub content_type { my ($r,$type,$charset) = @_; + &no_cache($r); if ($env{'browser.mathml'} && $type eq 'text/html') { $type='text/xml'; } unless ($charset) { $charset=&Apache::lonlocal::current_encoding;