# The LearningOnline Network with CAPA # # $Id: loncoursegroups.pm,v 1.28 2006/06/28 16:01:01 albertel 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::loncoursegroups; use strict; use Apache::lonnet; use Apache::loncommon; use Apache::lonhtmlcommon; use Apache::lonlocal; use Apache::lonnavmaps; use Apache::longroup; use Apache::Constants qw(:common :http); use lib '/home/httpd/lib/perl/'; use LONCAPA; sub handler { my ($r) = @_; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; if ($r->header_only) { return OK; } # Needs to be in a course if (! ($env{'request.course.fn'})) { # Not in a course $env{'user.error.msg'}= "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups"; return HTTP_NOT_ACCEPTABLE; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','refpage','state','groupname','branch']); my $function = &Apache::loncommon::get_users_function(); my $tabcol = &Apache::loncommon::designparm($function.'.tabbg'); my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $view_permission = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}); my $manage_permission = &Apache::lonnet::allowed('mdg',$env{'request.course.id'}); &Apache::lonhtmlcommon::clear_breadcrumbs(); my %functions = ( email => 'E-mail', discussion => 'Discussion boards', chat => 'Chat', files => 'File repository', roster => 'Membership roster', homepage => 'Group home page', ); my %idx = (); $idx{id} = &Apache::loncoursedata::CL_ID(); $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME(); $idx{udom} = &Apache::loncoursedata::CL_SDOM(); $idx{uname} = &Apache::loncoursedata::CL_SNAME(); my $rowColor1 = "#dddddd"; my $rowColor2 = "#eeeeee"; my $action = $env{'form.action'}; my $state = $env{'form.state'}; if ((!defined($action)) || ($action eq 'view')) { if (!defined($state)) { $state = 'view'; } } if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { if ($view_permission || $manage_permission) { &group_administration($r,$action,$state,$cdom,$cnum,$function, $tabcol,\%functions,\%idx,$view_permission, $manage_permission,$rowColor1,$rowColor2); } else { $r->print(&mt('You do not have group administration '. 'privileges in this course')); } } else { &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx, $view_permission,$manage_permission,$action,$state, $rowColor1,$rowColor2); } return OK; } sub print_main_menu { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, $manage_permission,$action,$state,$rowColor1,$rowColor2) = @_; my $jscript = qq| function changeSort(caller) { document.$state.sortby.value = caller; document.$state.submit(); }\n|; $r->print(&header('Course Groups',$jscript,$action,$state, undef,$function)); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", text=>"Course Groups",}); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Groups')); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission,$action,$state, $rowColor1,$rowColor2); $r->print(&footer()); return; } sub display_groups { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, $manage_permission,$action,$state,$rowColor1,$rowColor2) = @_; my %curr_groups = (); my %grp_info = (); my %actionlinks = ( modify => ' ' $lt{'act'} $lt{'gname'} $lt{'desc'} $lt{'crea'} $lt{'crtd'} $lt{'last'} $lt{'func'} $lt{'quot'} $lt{'memb'} $lt{'file'} $lt{'dibd'} $lt{'dius'} END my %Sortby = (); foreach my $group (sort(keys(%curr_groups))) { %{$grp_info{$group}} = &Apache::longroup::get_group_settings( $curr_groups{$group}); my $members_result = &group_members($cdom,$cnum,$group, \%grp_info); my $files_result = &group_files($group,\%grp_info); if ($env{'form.sortby'} eq 'groupname') { push(@{$Sortby{$group}},$group); } elsif ($env{'form.sortby'} eq 'description') { push(@{$Sortby{$grp_info{$group}{'description'}}}, $group); } elsif ($env{'form.sortby'} eq 'creator') { push(@{$Sortby{$grp_info{$group}{'creator'}}},$group); } elsif ($env{'form.sortby'} eq 'creation') { push(@{$Sortby{$grp_info{$group}{'creation'}}},$group); } elsif ($env{'form.sortby'} eq 'modified') { push(@{$Sortby{$grp_info{$group}{'modified'}}},$group); } elsif ($env{'form.sortby'} eq 'quota') { push(@{$Sortby{$grp_info{$group}{'quota'}}},$group); } elsif ($env{'form.sortby'} eq 'totalmembers') { push(@{$Sortby{$grp_info{$group}{'totalmembers'}}}, $group); } elsif ($env{'form.sortby'} eq 'totalfiles') { push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},$group); } elsif ($env{'form.sortby'} eq 'boards') { push(@{$Sortby{$grp_info{$group}{'boards'}}},$group); } elsif ($env{'form.sortby'} eq 'diskuse') { push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group); } else { push(@{$Sortby{$group}},$group); } } my $rowNum = 0; my $rowColor; foreach my $key (sort(keys(%Sortby))) { foreach my $group (@{$Sortby{$key}}) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } my $description = &unescape($grp_info{$group}{'description'}); my $creator = $grp_info{$group}{'creator'}; my $creation = $grp_info{$group}{'creation'}; my $modified = $grp_info{$group}{'modified'}; my $quota = $grp_info{$group}{'quota'}; my $totalmembers = $grp_info{$group}{'totalmembers'}; my $totalfiles = $grp_info{$group}{'totalfiles'}; my $boards = $grp_info{$group}{'boards'}; my $diskuse = $grp_info{$group}{'diskuse'}; my $functionality; foreach my $tool (sort(keys(%{$functions}))) { if ($grp_info{$group}{functions}{$tool} eq 'on') { $functionality .= ' '.$tool; } } if (!$functionality) { $functionality = &mt('None available'); } my $link = $actionlinks{$action}; if ($action eq 'modify' || $action eq 'delete') { $link .= $group; } else { $link .= $group.'/grppg'; } $link .= '">'.$lt{$action}.''; if ($action eq 'view') { if (($manage_permission) && ($env{'form.refpage'} ne 'enrl')) { $link .= '  '.$actionlinks{'modify'}. $group.'">'.$lt{'modify'}.''; } } $r->print(''.$link.''.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.$totalfiles.''.$boards.''.$diskuse.''); $rowNum ++; } } $r->print(''); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print(''); if ($action eq 'view') { if (!defined($state)) { $state = 'view'; } $r->print(''); } } else { $r->print($lt{'nogr'}); if ($manage_permission) { $r->print('

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

'.$lt{'crng'}); } } } else { my @coursegroups = split(/:/,$env{'request.course.groups'}); if (@coursegroups > 0) { $r->print('

'); my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum); if (%curr_groups) { foreach my $group (@coursegroups) { my %group_info = &Apache::longroup::get_group_settings( $curr_groups{$group}); my $description = &unescape( $group_info{description}); my ($uname,$udom) = split(/:/,$group_info{creator}); $r->print(''.$group,'
'.$description.'

'); } } } else { $r->print(&mt('You are not currently a member of any '. 'active groups in this course')); } } return; } sub group_administration { my ($r,$action,$state,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission,$rowColor1,$rowColor2) = @_; my %sectioncount = (); my @tools = (); my @types = (); my @roles = (); my @sections = (); my %users = (); my %userdata = (); my @members = (); my %usertools = (); my %stored = (); my %memchg; my @member_changes = ('deletion','expire','activate','reenable', 'changefunc','changepriv'); my ($groupname,$description,$startdate,$enddate,$granularity,$specificity); if (defined($env{'form.groupname'})) { $groupname = $env{'form.groupname'}; } if (($action eq 'create') && ($state eq '')) { $state = 'pick_name'; } if (($action eq 'create') || (($action eq 'modify') && ($state eq 'chgresult'))) { ($startdate,$enddate) = &get_dates_from_form(); if (defined($env{'form.description'})) { $description = $env{'form.description'}; } if (defined($env{'form.tool'})) { @tools=&Apache::loncommon::get_env_multiple('form.tool'); } if (defined($env{'form.granularity'})) { $granularity=$env{'form.granularity'}; } if (defined($env{'form.specificity'})) { $specificity=$env{'form.specificity'}; } } if (($action eq 'create') || (($action eq 'modify') && (($state eq 'pick_privs') || ($state eq 'addresult')))) { if (defined($env{'form.member'})) { @members = &Apache::loncommon::get_env_multiple('form.member'); foreach my $user (@members) { %{$usertools{$user}} = (); } } } if ($action eq 'modify') { if ($state eq '') { if (defined($env{'form.groupname'})) { $state = 'pick_task'; } else { $state = 'pick_group'; } } else { %stored = &retrieve_settings($cdom,$cnum,$groupname); if (ref($stored{'types'}) eq 'ARRAY') { @types = @{$stored{'types'}}; } if (ref($stored{'roles'}) eq 'ARRAY') { @roles = @{$stored{'roles'}}; } if (ref($stored{'sectionpick'}) eq 'ARRAY') { @sections = @{$stored{'sectionpick'}}; } unless ($state eq 'chgresult') { if (ref($stored{'tool'}) eq 'ARRAY') { @tools = @{$stored{'tool'}}; } $startdate = $stored{'startdate'}; $enddate = $stored{'enddate'}; $description = $stored{'description'}; $granularity = $stored{'granularity'}; $specificity = $stored{'specificity'}; } } } my %toolprivs = ( email => { sgm => 'Send group mail', sgb => 'Broadcast mail', }, discussion => { cgb => 'Create boards', pgd => 'Post', pag => 'Anon. posts', rgi => 'Get identities', vgb => 'View boards', }, chat => { pgc => 'Chat', }, files => { rgf => 'Retrieve', ugf => 'Upload', mgf => 'Modify', dgf => 'Delete', agf => 'Control Access', }, roster => { vgm => 'View', }, homepage => { vgh => 'View page', mgh => 'Modify page', }, ); my %fixedprivs = ( email => {sgm => 1}, discussion => {vgb => 1}, chat => {pgc => 1}, files => {rgf => 1}, roster => {vgm => 1}, homepage => {vgh => 1}, ); my %elements = ( create => { pick_name => { startdate_month => 'selectbox', startdate_hour => 'selectbox', enddate_month => 'selectbox', enddate_hour => 'selectbox', startdate_day => 'text', startdate_year => 'text', startdate_minute => 'text', startdate_second => 'text', enddate_day => 'text', enddate_year => 'text', enddate_minute => 'text', enddate_second => 'text', groupname => 'text', description => 'text', tool => 'checkbox', granularity => 'radio', no_end_date => 'checkbox', }, pick_members => { member => 'checkbox', defpriv => 'checkbox', }, }, ); $elements{'modify'} = { change_settings => { %{$elements{'create'}{'pick_name'}}, specificity => 'radio', defpriv => 'checkbox', autorole => 'checkbox', autoadd => 'radio', autodrop => 'radio', }, add_members => { types => 'selectbox', roles => 'selectbox', }, }; if (ref($stored{'autorole'}) eq 'ARRAY') { foreach my $role (@{$stored{'autorole'}}) { unless ($role eq 'cc') { $elements{'modify'}{'change_settings'}{'sec_'.$role} = 'selectbox'; } } } if (($action eq 'create') && ($state eq 'pick_name')) { $elements{'create'}{'pick_name'}{'types'} = 'selectbox'; $elements{'create'}{'pick_name'}{'roles'} = 'selectbox'; } if ((($action eq 'create') && (($state eq 'pick_name') || ($state eq 'pick_privs'))) || (($action eq 'modify') && (($state eq 'change_settings') || ($state eq 'add_members')))) { %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum); if (%sectioncount) { $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox'; $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox'; $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox'; } } if (($action eq 'create') || ($action eq 'modify' && $state eq 'pick_members')) { if (defined($env{'form.types'})) { @types=&Apache::loncommon::get_env_multiple('form.types'); } if (defined($env{'form.roles'})) { @roles=&Apache::loncommon::get_env_multiple('form.roles'); } if (defined($env{'form.sectionpick'})) { @sections=&Apache::loncommon::get_env_multiple('form.sectionpick'); if (grep/^all$/,@sections) { @sections = sort {$a cmp $b} keys(%sectioncount); } } } if (($state eq 'pick_members') || ($state eq 'pick_privs') || ($state eq 'change_privs')) { &build_members_list($cdom,$cnum,\@types,\@roles,\@sections,\%users, \%userdata); } if ($state eq 'pick_members') { if ((keys(%users) > 0) && (@tools > 0)) { if ($granularity eq 'Yes') { $elements{$action}{'pick_members'}{'togglefunc'} = 'checkbox'; } foreach my $tool (@tools) { if ($granularity eq 'Yes') { $elements{$action}{'pick_members'}{'user_'.$tool} = 'checkbox'; } } $elements{$action}{'pick_members'}{'specificity'} = 'radio'; } } if ($state eq 'change_members') { my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, $groupname); my $now = time; my $num_expire = 0; my $num_activate = 0; my $num_reenable = 0; my $num_deletion = 0; my $numusers = 0; foreach my $key (sort(keys(%membership))) { if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { my $user = $1; my($end,$start,@userprivs) = split(/:/,$membership{$key}); unless ($start == -1) { $numusers ++; $num_deletion ++; if (($end > 0) && ($end < $now)) { $num_reenable ++; next; } elsif (($start > $now)) { $num_activate = 1; next; } else { $num_expire ++; next; } next; } if ($num_reenable && $num_activate && $num_expire) { last; } } } if ($num_deletion) { $elements{$action}{'change_members'}{'deletion'} = 'checkbox'; } if ($num_expire) { $elements{$action}{'change_members'}{'expire'} = 'checkbox'; } if ($num_activate) { $elements{$action}{'change_members'}{'activate'} = 'checkbox'; } if ($num_reenable) { $elements{$action}{'change_members'}{'reenable'} = 'checkbox'; } if ($numusers) { if ($granularity eq 'Yes') { $elements{$action}{'change_members'}{'togglefunc'} = 'checkbox'; } foreach my $tool (@tools) { if ($granularity eq 'Yes') { $elements{$action}{'change_members'}{'user_'.$tool} = 'checkbox'; } } if ($specificity eq 'Yes') { $elements{$action}{'change_members'}{'changepriv'} = 'checkbox'; } } } if (($state eq 'pick_privs') || ($state eq 'change_privs') || (($specificity eq 'No') && ($state eq 'memresult' || $state eq 'result' || $state eq 'addresult'))) { foreach my $tool (@tools) { my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool); foreach my $user (@values) { if ($state eq 'pick_privs' || $state eq 'result' || $state eq 'addresult') { if (!grep(/^\Q$user\E$/,@members)) { next; } } unless(exists($usertools{$user}{$tool})) { $usertools{$user}{$tool} = 1; } } } } if (($action eq 'modify') && (($state eq 'change_privs') || ($state eq 'memresult'))) { foreach my $chg (@member_changes) { if (defined($env{'form.'.$chg})) { @{$memchg{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg); } } if ($state eq 'change_privs') { my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, $groupname); my $now = time; foreach my $key (sort(keys(%membership))) { if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { my $user = $1; my $changefunc = 0; my ($end,$start,@userprivs) = split(/:/,$membership{$key}); unless ($start == -1) { if (($end > 0) && ($end < $now)) { unless (grep/^$user$/,$memchg{'reenable'}) { next; } } my @currtools = (); if (@userprivs > 0) { foreach my $tool (sort(keys(%fixedprivs))) { foreach my $priv (keys(%{$fixedprivs{$tool}})) { if (grep/^$priv$/,@userprivs) { push(@currtools,$tool); last; } } } } foreach my $tool (@currtools) { if (keys(%{$usertools{$user}}) > 0) { if (!$usertools{$user}{$tool}) { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; last; } } else { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; } } if ($changefunc) { next; } if (keys(%{$usertools{$user}}) > 0) { foreach my $tool (keys(%{$usertools{$user}})) { if (!grep/^$tool$/,@currtools) { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; last; } } } } } } &check_changes(\@member_changes,\%memchg); my %temptools; foreach my $change (@member_changes) { if (($change eq 'deletion') || ($change eq 'expire')) { next; } foreach my $user (@{$memchg{$change}}) { unless (exists($usertools{$user})) { %{$usertools{$user}} = (); } %{$temptools{$user}} = %{$usertools{$user}}; } } %usertools = %temptools; } elsif ($state eq 'memresult') { foreach my $change (@member_changes) { if ($change eq 'expire' || $change eq 'deletion') { next; } if (ref($memchg{$change}) eq 'ARRAY') { my @users = @{$memchg{$change}}; foreach my $user (@users) { unless (exists($usertools{$user})) { %{$usertools{$user}} = (); } } } } } } if ((($state eq 'pick_privs') || ($state eq 'change_privs')) && ($specificity eq 'Yes')) { foreach my $user (sort(keys(%usertools))) { foreach my $tool (keys(%{$usertools{$user}})) { foreach my $priv (keys(%{$toolprivs{$tool}})) { unless (exists($fixedprivs{$tool}{$priv})) { $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox'; } } } } } my $jscript = &Apache::loncommon::check_uncheck_jscript(); $jscript .= qq| function nextPage(formname,nextstate) { formname.state.value= nextstate; formname.submit(); } function backPage(formname,prevstate) { formname.state.value = prevstate; formname.submit(); } function changeSort(caller) { document.$state.state.value = '$state'; document.$state.sortby.value = caller; document.$state.submit(); } |; $jscript .= &Apache::lonhtmlcommon::set_form_elements( \%{$elements{$action}{$state}},\%stored); my $page = 0; my %states = (); my %branchstates = (); @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result'); @{$states{'modify'}} = ('pick_group','pick_task'); @{$branchstates{'noprivs'}} = ('result'); @{$branchstates{'settings'}} = ('change_settings','chgresult'); @{$branchstates{'members'}} = ('change_members','change_privs','memresult'); @{$branchstates{'adds'}} = ('add_members','pick_members','pick_privs', 'addresult'); if (defined($env{'form.branch'})) { push (@{$states{$action}},@{$branchstates{$env{'form.branch'}}}); } if (($action eq 'create') || ($action eq 'modify')) { my $done = 0; my $i=0; while ($i<@{$states{$action}} && !$done) { if ($states{$action}[$i] eq $state) { $page = $i; $done = 1; } $i++; } } my $loaditems = &onload_action($action,$state); $r->print(&header('Course Groups Manager', $jscript,$action,$state,$page,$function,$loaditems)); if ($env{'form.refpage'} eq 'enrl') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/dropadd", text=>"Enrollment Manager", faq=>9,bug=>'Instructor Interface',}); } else { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", text=>"Course Groups", faq=>9,bug=>'Instructor Interface',}); } my %trail = (); %{$trail{'create'}} = &Apache::lonlocal::texthash ( pick_name => 'Group Settings', pick_members => 'Select Members', pick_privs => 'Choose Privileges', result => 'Creation Complete', ); %{$trail{'modify'}} = &Apache::lonlocal::texthash( pick_group => 'Groups', pick_task => 'Choose Task', change_settings => 'Group Settings', change_members => 'Modify/Delete Members', change_privs => 'Change Privileges', change_mapping => 'Membership Mapping', add_members => 'Add Members', pick_members => 'Select Members', pick_privs => 'Choose Privileges', chgresult => 'Setting Changes Complete', memresult => 'Modifications Complete', addresult => 'Additions Complete', ); my %navbuttons = &Apache::lonlocal::texthash( gtns => 'Go to next step', gtps => 'Go to previous step', crgr => 'Create group', mose => 'Modify settings', gtpp => 'Go to previous page', adme => 'Add members', ); if ((($action eq 'create') || ($action eq 'modify')) && ($manage_permission)) { for (my $i=0; $i<@{$states{$action}}; $i++) { if ($state eq $states{$action}[$i]) { &Apache::lonhtmlcommon::add_breadcrumb( {text=>"$trail{$action}{$state}"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs ('Course Groups Manager')); &display_control($r,$cdom,$cnum,$tabcol,$action,$state,$page, \%sectioncount,$groupname,$description,$functions, \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate, \%users,\%userdata,$idx,\%memchg,\%usertools, $function,$view_permission,$manage_permission, \%stored,$granularity,$specificity,\@types,\@roles, \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2); last; } else { if (($state eq 'result') && ($i > 0)) { &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[0]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } else { &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } } } } elsif (($action eq 'view') && ($view_permission)) { &Apache::lonhtmlcommon::add_breadcrumb( {text=>"View groups"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs ('Course Groups Manager')); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission,$action,$state, $rowColor1,$rowColor2); } $r->print(&footer()); return; } sub retrieve_settings { my ($cdom,$cnum,$groupname) = @_; my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum,$groupname); return if (!%curr_groups); my %groupinfo = &Apache::longroup::get_group_settings($curr_groups{$groupname}); my %stored; $stored{'description'} = &unescape($groupinfo{'description'}); $stored{'startdate'} = $groupinfo{'startdate'}; $stored{'enddate'} = $groupinfo{'enddate'}; if ($stored{'enddate'} == 0) { $stored{'no_end_date'} = 1; } $stored{'granularity'} = $groupinfo{'granularity'}; $stored{'specificity'} = $groupinfo{'specificity'}; $stored{'creation'} = $groupinfo{'creation'}; $stored{'creator'} = $groupinfo{'creator'}; foreach my $tool (sort(keys(%{$groupinfo{'functions'}}))) { if ($groupinfo{functions}{$tool} eq 'on') { push(@{$stored{tool}},$tool); } } foreach my $role (@{$groupinfo{'roles'}}) { push(@{$stored{roles}},$role); } foreach my $type (@{$groupinfo{'types'}}) { push(@{$stored{types}},$type); } foreach my $section (@{$groupinfo{'sectionpick'}}) { push(@{$stored{sectionpick}},$section); } foreach my $defpriv (@{$groupinfo{'defpriv'}}) { push(@{$stored{defpriv}},$defpriv); } $stored{'autoadd'} = $groupinfo{'autoadd'}; $stored{'autodrop'} = $groupinfo{'autodrop'}; if (exists($groupinfo{'autosec'})) { foreach my $role (sort(keys(%{$groupinfo{'autosec'}}))) { if (ref($groupinfo{'autosec'}{$role}) eq 'ARRAY') { foreach my $section (@{$groupinfo{'autosec'}{$role}}) { push (@{$stored{'sec_'.$role}},$section); } if (@{$groupinfo{'autosec'}{$role}} > 0) { push(@{$stored{'autorole'}},$role); } } } } return %stored; } sub display_control { my ($r,$cdom,$cnum,$tabcol,$action,$state,$page,$sectioncount,$groupname, $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate, $enddate,$users,$userdata,$idx,$memchg,$usertools,$function, $view_permission,$manage_permission,$stored,$granularity,$specificity, $types,$roles,$sections,$states,$navbuttons,$rowColor1,$rowColor2)=@_; if ($action eq 'create') { if ($state eq 'pick_name') { &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page, $functions,$tools,$toolprivs,$fixedprivs, $sectioncount,$stored,$states,$navbuttons, $rowColor1,$rowColor2); } elsif ($state eq 'pick_members') { &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $groupname,$description,$granularity, $startdate,$enddate,$tools,$fixedprivs, $toolprivs,$functions,$users,$userdata,$idx, $stored,$states,$navbuttons,$rowColor1, $rowColor2); } elsif ($state eq 'pick_privs') { &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $startdate,$enddate,$tools,$functions, $toolprivs,$fixedprivs,$userdata,$usertools, $idx,$states,$stored,$sectioncount,$navbuttons, $rowColor1,$rowColor2); } elsif ($state eq 'result') { &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page, $groupname,$description,$specificity,$userdata, $startdate,$enddate,$tools,$functions, $toolprivs,$usertools,$idx,$types,$roles, $sections,$states,$navbuttons,$memchg, $sectioncount,$stored,$rowColor1,$rowColor2); } } elsif ($action eq 'modify') { my $groupname = $env{'form.groupname'}; if ($state eq 'pick_group') { &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission,$action,$state, $rowColor1,$rowColor2); } elsif ($state eq 'pick_task') { &modify_menu($r,$groupname,$page); } elsif ($state eq 'change_settings') { &general_settings_form($r,$cdom,$cnum,$action,$tabcol,$state,$page, $functions,$tools,$toolprivs,$fixedprivs, $sectioncount,$stored,$states,$navbuttons, $rowColor1,$rowColor2); } elsif ($state eq 'change_members') { &change_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $groupname,$description,$startdate,$enddate, $tools,$fixedprivs,$functions,$users, $userdata,$granularity,$specificity,$idx, $states,$navbuttons,$rowColor1,$rowColor2); } elsif ($state eq 'add_members') { &add_members_form($r,$tabcol,$action,$state,$page,$startdate, $enddate,$groupname,$description,$granularity, $sectioncount,$tools,$functions,$stored,$states, $navbuttons,$rowColor1,$rowColor2); } elsif ($state eq 'pick_members') { &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $groupname,$description,$granularity, $startdate,$enddate,$tools,$fixedprivs, $toolprivs,$functions,$users,$userdata,$idx, $stored,$states,$navbuttons,$rowColor1, $rowColor2); } elsif ($state eq 'pick_privs') { &choose_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $startdate,$enddate,$tools,$functions, $toolprivs,$fixedprivs,$userdata,$usertools, $idx,$states,$stored,$sectioncount,$navbuttons, $rowColor1,$rowColor2); } elsif ($state eq 'change_privs') { &change_privs_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, $startdate,$enddate,$tools,$functions, $toolprivs,$fixedprivs,$userdata,$usertools, $memchg,$idx,$states,$stored,$sectioncount, $navbuttons,$rowColor1,$rowColor2); } elsif ($state eq 'chgresult' || $state eq 'memresult' || $state eq 'addresult') { &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page, $groupname,$description,$specificity,$userdata, $startdate,$enddate,$tools,$functions, $toolprivs,$usertools,$idx,$types,$roles, $sections,$states,$navbuttons,$memchg, $sectioncount,$stored,$rowColor1,$rowColor2); } } } sub header { my ($bodytitle,$jscript,$action,$state,$page,$function,$loaditems) = @_; my $start_page= &Apache::loncommon::start_page($bodytitle, '', {'function' => $function, 'add_entries' => $loaditems,}); my $output = <<"END"; $start_page
END if ($action eq 'create' || $action eq 'modify') { $output .= <<"END"; END } return $output; } sub onload_action { my ($action,$state) = @_; my %loaditems; if ((defined($env{'form.origin'})) && ($action eq 'create') && ($state eq 'pick_name' || $state eq 'pick_members' || $state eq 'pick_privs')) { unless ($env{'form.origin'} eq '') { $loaditems{'onload'} = 'javascript:setFormElements(document.'.$state.')'; } } if (($action eq 'modify') && ($state eq 'change_settings' || $state eq 'change_members' || $state eq 'change_privs' || $state eq 'add_members' || $state eq 'pick_members')) { $loaditems{'onload'} = 'javascript:setFormElements(document.'.$state.')'; } return \%loaditems; } sub footer { my $end_page = &Apache::loncommon::end_page(); return(< $end_page ENDFOOT } sub build_members_list { my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_; my %access = (); foreach my $role (@{$roles}) { %{$$users{$role}} = (); } foreach my $type (@{$types}) { $access{$type} = $type; } &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles, $sections,$users,$userdata); return; } sub group_files { return; } sub group_members { my ($cdom,$cnum,$group,$group_info) = @_; my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group); my $now = time; my ($tmp)=keys(%memberhash); if ($tmp=~/^error:/) { $$group_info{'totalmembers'} = 'Unknown - an error occurred'; return $tmp; } my $totalmembers = 0; my $active = 0; my $previous = 0; my $future = 0; foreach my $member (keys %memberhash) { $totalmembers ++; my ($end,$start) = split(/:/,$memberhash{$member}); unless ($start == -1) { if (($end!=0) && ($end<$now)) { $previous ++; } elsif (($start!=0) && ($start>$now)) { $future ++; } else { $active ++; } } } if ($totalmembers == 0) { $$group_info{$group}{'totalmembers'} = 'None'; } else { $$group_info{$group}{'totalmembers'} = $active.' - active
'.$previous.' -previous
'.$future.' -future'; } return 'ok'; } sub general_settings_form { my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools, $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons, $rowColor1,$rowColor2) = @_; my ($nexttext,$prevtext); $r->print('
'); &groupsettings_options($r,$tabcol,$functions,$action,$formname,$stored,1); $r->print(' '); &access_date_settings($r,$tabcol,$action,$formname,$stored,2); $r->print(' '); if ($action eq 'create') { &membership_options($r,$action,$formname,$tabcol,$sectioncount,3); $nexttext = $$navbuttons{'gtns'}; } else { my @available = (); my @unavailable = (); &check_tools($functions,$tools,\@available,\@unavailable); @{$tools} = sort(keys(%{$functions})); &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action, 3,$tools,$stored,$toolprivs,$fixedprivs, \@available,$formname); $r->print(' '); &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount, $states,$stored,$navbuttons,4,5,$rowColor1, $rowColor2); $nexttext = $$navbuttons{'mose'}; } $prevtext = $$navbuttons{'gtpp'}; &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); $r->print('
 
 
 
'); return; } sub groupsettings_options { my ($r,$tabcol,$functions,$action,$formname,$stored,$image) = @_; my %lt = &Apache::lonlocal::texthash( 'gdat' => 'Group open and close dates', 'sten' => 'Set a start date/time and end date/time for the group', 'gfun' => 'Group functionality', 'gnde' => 'Group name, description and available functionality', 'desc' => 'Description', 'func' => 'Functionality', 'gnam' => 'Group Name', 'doyo' => 'Do you want to assign different functionality '. 'to different group members?', ); &topic_bar($r,$tabcol,$image,$lt{'gnde'}); $r->print('   END my $numitems = keys(%{$functions}); my $halfnum = int($numitems/2); my $remnum = $numitems%2; if ($remnum) { $halfnum ++; } my @allfunctions = sort(keys (%{$functions})); for (my $i=0; $i<$halfnum; $i++) { $r->print(''); } $r->print(''); for (my $j=$halfnum; $j<@allfunctions; $j++) { $r->print(''); } if ($remnum) { $r->print(''); } $r->print('
'.$lt{'gnam'}.': '); if ($action eq 'create') { $r->print(''); } else { $r->print(''.$env{'form.groupname'}); } $r->print(<<"END");
$lt{'desc'}:
$lt{'func'}:   '. '
     
Granularity: '.$lt{'doyo'}.'  '); if ($action eq 'modify') { $r->print('  ('.&mt('Currently set to "[_1]"', $$stored{'granularity'}).')'); } $r->print('
'); return; } sub membership_options { my ($r,$action,$state,$tabcol,$sectioncount,$image) = @_; my %lt = &Apache::lonlocal::texthash( 'pipa' => 'Pick parameters to generate membership list', 'gmem' => 'Group membership options', 'picr' => 'Pick the criteria to use to build a list of '. 'course users from which you will select ', 'meof' => 'members of the new group.', 'admg' => 'additional members of the group.', 'ifno' => 'If you do not wish to add members when you first '. 'create the group, do not make any selections.', 'asub' => 'A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified role and section changes.', 'acty' => 'Access types', 'coro' => 'Course roles', 'cose' => 'Course sections', ); my %status_types = ( active => &mt('Currently has access'), previous => &mt('Previously had access'), future => &mt('Will have future access'), ); my @roles = ('st','cc','in','ta','ep','cr'); my @sections = keys(%{$sectioncount}); &topic_bar($r,$tabcol,$image,$lt{'pipa'}); $r->print('   '.$lt{'gmem'}.'
'.$lt{'picr'}); if ($action eq 'create') { $r->print($lt{'meof'}.'
'.$lt{'ifno'}.'
'.$lt{'asub'}); } else { $r->print($lt{'admg'}); } $r->print('

'); if (@sections >0) { $r->print(' '); } $r->print(''); $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types)); $r->print(''); $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles)); if (@sections > 0) { @sections = sort {$a cmp $b} @sections; unshift(@sections,'all'); # Put 'all' at the front of the list unshift(@sections,'none'); # Put 'no sections' next $r->print(''); } $r->print('
'.$lt{'acty'}.'   '.$lt{'coro'}.'  '.$lt{'cose'}.'  
   '. §ions_selection(\@sections,'sectionpick').'
'); return; } sub sections_selection { my ($sections,$elementname) = @_; my $section_sel; my $numvisible = 4; if (@{$sections} < 4) { $numvisible = @{$sections}; } foreach my $sec (@{$sections}) { if ($sec eq 'all') { $section_sel .= '