--- loncom/interface/loncoursegroups.pm 2005/11/22 00:01:41 1.4 +++ loncom/interface/loncoursegroups.pm 2006/11/20 23:49:49 1.64 @@ -1,3 +1,6 @@ +# The LearningOnline Network with CAPA +# +# $Id: loncoursegroups.pm,v 1.64 2006/11/20 23:49:49 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,18 +29,23 @@ package Apache::loncoursegroups; use strict; use Apache::lonnet; -use Apache::loncommon; -use Apache::lonhtmlcommon; +use Apache::loncommon(); +use Apache::lonhtmlcommon(); use Apache::lonlocal; -use Apache::lonnavmaps; +use Apache::lonnavmaps(); +use Apache::longroup(); +use Apache::portfolio(); use Apache::Constants qw(:common :http); +use LONCAPA::map(); +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; } @@ -51,27 +59,28 @@ sub handler { } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['action','refpage']); - - my $function = &Apache::loncommon::get_users_function(); - my $tabcol = &Apache::loncommon::designparm($function.'.tabbg'); + ['action','refpage','state','groupname','branch']); 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'}); + &Apache::lonnet::allowed('vcg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); my $manage_permission = - &Apache::lonnet::allowed('mdg',$env{'request.course.id'}); - + &Apache::lonnet::allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); &Apache::lonhtmlcommon::clear_breadcrumbs(); + my $gpterm = &Apache::loncommon::group_term(); + my $ucgpterm = $gpterm; + $ucgpterm =~ s/^(\w)/uc($1)/e; + my $crstype = &Apache::loncommon::course_type(); + my %functions = ( email => 'E-mail', discussion => 'Discussion boards', chat => 'Chat', files => 'File repository', roster => 'Membership roster', - homepage => 'Group home page', + homepage => $ucgpterm.' home page', ); my %idx = (); @@ -79,86 +88,167 @@ sub handler { $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME(); $idx{udom} = &Apache::loncoursedata::CL_SDOM(); $idx{uname} = &Apache::loncoursedata::CL_SNAME(); + $idx{section} = &Apache::loncoursedata::CL_SECTION(); my $action = $env{'form.action'}; - if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { + my $state = $env{'form.state'}; + if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify') || ($action eq 'delete')) { + if (!defined($state)) { + $state = 'view'; + } + } + if ($action eq 'create' || $action eq 'modify' || $action eq 'view' || + $action eq 'delete') { if ($view_permission || $manage_permission) { - &group_administration($r,$action,$cdom,$cnum,$function,$tabcol, - \%functions,\%idx,$view_permission,$manage_permission); + if ($state eq 'view') { + &print_main_menu($r,$cdom,$cnum,\%functions,\%idx, + $view_permission,$manage_permission, + $action,$state,$gpterm,$ucgpterm,$crstype); + } else { + &group_administration($r,$action,$state,$cdom,$cnum, + \%functions,\%idx,$view_permission, + $manage_permission,$gpterm,$ucgpterm, + $crstype); + } } else { - $r->print('You do not have group administration '. - 'privileges in this course'); + $r->print(&mt('You do not have [_1] administration '. + 'privileges in this [_2]',$gpterm,lc($crstype))); } } else { - &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx, - $view_permission,$manage_permission); + &print_main_menu($r,$cdom,$cnum,\%functions,\%idx,$view_permission, + $manage_permission,$action,$state,$gpterm,$ucgpterm, + $crstype); } return OK; } sub print_main_menu { - my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, - $manage_permission) - = @_; - $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'), - undef,undef,undef,$function)); + my ($r,$cdom,$cnum,$functions,$idx,$view_permission,$manage_permission, + $action,$state,$gpterm,$ucgpterm,$crstype) = @_; + my $jscript = qq| +function changeSort(caller) { + document.$state.sortby.value = caller; + document.$state.submit(); +} +function openGroupRoster(group,status) { + var url = '/adm/grouproster?'; + url += 'group='+group+'&status='+status+'&ref=popup'; + var title = 'Group Membership'; + var options = 'scrollbars=1,resizable=1,menubar=0'; + options += ',width=700,height=600'; + rosterbrowser = open(url,title,options,'1'); + rosterbrowser.focus(); +}\n|; + $r->print(&header('Groups',$jscript,$action,$state)); + if ($env{'form.refpage'} eq 'enrl') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/dropadd", + text=>"Enrollment Manager"}); + } &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", - text=>"Course Groups",}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,'Course Groups')); - &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, - $view_permission,$manage_permission); + text=>"Groups"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Groups')); + &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission, + $manage_permission,$action,$state,$gpterm,$ucgpterm, + $crstype); $r->print(&footer()); return; } sub display_groups { - my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, - $manage_permission) = @_; + my ($r,$cdom,$cnum,$functions,$idx,$view_permission, + $manage_permission,$action,$state,$gpterm,$ucgpterm,$crstype) = @_; my %curr_groups = (); my %grp_info = (); - my $rowColor1 = "#dddddd"; - my $rowColor2 = "#eeeeee"; - - $r->print('

'); + my %actionlinks = ( + modify => ' ''.$lt{'crng'}.''); + } + } + $r->print('

'); + $r->print(&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row()); + $r->print(<<"END"); - - - - - - - - - - - - - - - + + + + + + + + + + + END + $r->print(&Apache::loncommon::end_data_table_header_row()); my %Sortby = (); foreach my $group (sort(keys(%curr_groups))) { %{$grp_info{$group}} = - &Apache::loncommon::get_group_settings( + &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); + my $members_result = &group_members($cdom,$cnum,$group, + \%grp_info); + my $port_path = '/userfiles/groups/'.$group.'/portfolio'; + my $port_dir = &Apache::loncommon::propath($cdom,$cnum).$port_path; + my $totaldirs = 0; + my $totalfiles = 0; + &group_files($group,$port_dir,\$totalfiles,\$totaldirs); + $grp_info{$group}{'totalfiles'} = $totalfiles; + $grp_info{$group}{'totaldirs'} = $totaldirs; + my $diskuse = &Apache::lonnet::diskusage($cdom,$cnum,$port_dir); + if ($grp_info{$group}{'quota'} > 0) { + my $pct_use = 0.1 * $diskuse/$grp_info{$group}{'quota'}; + $grp_info{$group}{'diskuse'} = sprintf("%.0f",$pct_use); + } else { + $grp_info{$group}{'diskuse'} = 'N/A'; + } + my ($groupboards,$boardshash)=&Apache::longroup::get_group_bbinfo( + $cdom,$cnum,$group); + $grp_info{$group}{'boards'} = scalar(@{$groupboards}); if ($env{'form.sortby'} eq 'groupname') { push(@{$Sortby{$group}},$group); } elsif ($env{'form.sortby'} eq 'description') { - push(@{$Sortby{$grp_info{$group}{'description'}}}, - $group); + 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') { @@ -171,8 +261,7 @@ END push(@{$Sortby{$grp_info{$group}{'totalmembers'}}}, $group); } elsif ($env{'form.sortby'} eq 'totalfiles') { - push(@{$Sortby{$grp_info{$group}{'totalfiles'}}}, - $group); + 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') { @@ -181,176 +270,267 @@ END 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 = - &Apache::lonnet::unescape($grp_info{$group}{'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 $totaldirs = $grp_info{$group}{'totaldirs'}; my $boards = $grp_info{$group}{'boards'}; my $diskuse = $grp_info{$group}{'diskuse'}; my $functionality; - foreach my $tool (sort keys(%{$functions})) { - if (defined($grp_info{$group}{functions}{$tool})) { + foreach my $tool (sort(keys(%{$functions}))) { + if ($grp_info{$group}{functions}{$tool} eq 'on') { $functionality .= ' '.$tool; } } if (!$functionality) { - $functionality = 'None available'; + $functionality = &mt('None available'); } - $r->print(''); - $rowNum ++; + my $link = $actionlinks{$action}; + if ($action eq 'modify' || $action eq 'delete') { + $link .= $group; + } else { + $link .= $group.'/smppg?ref=grouplist'; + if (exists($env{'form.refpage'})) { + $link .= '&refpage='.$env{'form.refpage'}; + } + } + $link .= '">'.$lt{$action}.''; + if ($action eq 'view') { + if (($manage_permission) && + ($env{'form.refpage'} ne 'enrl')) { + $link .= '  '.$actionlinks{'modify'}. + $group.'">'.$lt{'modify'}.''. + '  '.$actionlinks{'delete'}. + $group.'">'.$lt{'delete'}.''; + } + } + $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense'). + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + ''. + &Apache::loncommon::end_data_table_row()); } } - $r->print('
ActionGroup NameDescriptionCreator - Created - Last Modified - Functionality - Quota (Mb)MembersFilesDiscussion boardsDisk use
$lt{'act'}$lt{'gname'}$lt{'desc'}$lt{'crea'}$lt{'crtd'}$lt{'last'}$lt{'func'} + $lt{'quot'}$lt{'memb'}$lt{'file'}$lt{'dibd'}$lt{'dius'}
- View Modify'.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.$totalfiles.''.$boards.''.$diskuse.'
'.$link.''.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.&mt('Files: ').$totalfiles.'
'.&mt('Folders: ').$totaldirs.'
'.$boards.''.$diskuse.'
'); - $r->print(&Apache::lonhtmlcommon::end_pick_box()); + $r->print(&Apache::loncommon::end_data_table()); + $r->print(''); + if ($action eq 'view') { + if (!defined($state)) { + $state = 'view'; + } + $r->print(''); + } } else { - $r->print('No groups exist'); + $r->print($lt{'nogr'}); + if ($manage_permission) { + if (!exists($env{'form.refpage'})) { + $r->print('

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

'.$lt{'alth'}); + + } } } else { my @coursegroups = split(/:/,$env{'request.course.groups'}); if (@coursegroups > 0) { - my %curr_groups; - if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) { + $r->print('

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

'); + my %group_info = &Apache::longroup::get_group_settings( + $curr_groups{$group}); + my $description = &unescape( + $group_info{description}); + $r->print(''.$group,'
'.$description.'

'); } } } else { - $r->print('You are not currently a member of any active groups in this course'); + $r->print(&mt('You are not currently a member of any '. + 'active [_1]s in this [_2]',$gpterm, + lc($crstype))); } } return; } sub group_administration { - my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx, - $view_permission,$manage_permission) = @_; + my ($r,$action,$state,$cdom,$cnum,$functions,$idx,$view_permission, + $manage_permission,$gpterm,$ucgpterm,$crstype) = @_; my %sectioncount = (); my @tools = (); my @types = (); my @roles = (); my @sections = (); + my @buildsections = (); 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, + $quota,$validate_script); - my $state = $env{'form.state'}; - my ($groupname,$description,$startdate,$enddate); + if (defined($env{'form.groupname'})) { + $groupname = $env{'form.groupname'}; + } - if ($action eq 'create') { + 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 (defined($env{'form.quota'})) { + $quota=$env{'form.quota'}; + } + } + 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 '') { - $state = 'pick_name'; - } else { - ($startdate,$enddate) = &get_dates_from_form(); if (defined($env{'form.groupname'})) { - $groupname = $env{'form.groupname'}; + $state = 'pick_task'; } - 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.member'})) { - @members = &Apache::loncommon::get_env_multiple('form.member'); - foreach my $user (@members) { - %{$usertools{$user}} = (); + } 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'}; + $quota = $stored{'quota'}; + } + } + } + + my $toolprivs = &Apache::longroup::get_tool_privs($gpterm); + + my $fixedprivs = &Apache::longroup::get_fixed_privs(); + + 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', + quota => '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'; } } } - my %toolprivs = (); - %{$toolprivs{'email'}} = ( - sgm => 'Send group mail', - sgb => 'Broadcast mail', - ); - %{$toolprivs{'discussion'}} = ( - cgb => 'Create boards', - pgd => 'Post', - pag => 'Anon. posts', - rgi => 'Get identities', - vgb => 'View boards', - ); - %{$toolprivs{'chat'}} = ( - pgc => 'Chat', - ); - %{$toolprivs{'files'}} = ( - rgf => 'Retrieve', - ugf => 'Upload', - dgf => 'Delete', - ); - %{$toolprivs{'roster'}} = ( - vgm => 'View', - ); - %{$toolprivs{'homepage'}} = ( - vgh => 'View page', - mgh => 'Modify page', - ); - my %fixedprivs = (); - %{$fixedprivs{'email'}} = ('sgm' => 1); - %{$fixedprivs{'discussion'}} = ('vgb' => 1); - %{$fixedprivs{'chat'}} = ('pgc' => 1); - %{$fixedprivs{'files'}} = ('rgf' => 1); - %{$fixedprivs{'roster'}} = ('vgm' => 1); - %{$fixedprivs{'homepage'}} = ('vgh' => 1); - - my %elements = (); - %{$elements{'create'}} = (); - %{$elements{'modify'}} = (); - %{$elements{'create'}{'pick_name'}} = ( - startdate_month => 'selectbox', - startdate_hour => 'selectbox', - enddate_month => 'selectbox', - enddate_hour => 'selectbox', - types => 'selectbox', - roles => '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', - ); - %{$elements{'create'}{'pick_members'}} = ( - member => 'checkbox', - ); if (($action eq 'create') && ($state eq 'pick_name')) { - my $numsections = &Apache::loncommon::get_sections($cdom,$cnum, - \%sectioncount); - if ($numsections > 0) { - $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox'; - } + $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); + $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox'; + $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox'; + $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox'; } - - if (($action eq 'create') && (($state eq 'pick_members') || - ($state eq 'pick_privs'))) { + + if (($action eq 'create') || + ($action eq 'modify' && $state eq 'pick_members')) { if (defined($env{'form.types'})) { @types=&Apache::loncommon::get_env_multiple('form.types'); } @@ -359,171 +539,689 @@ sub group_administration { } 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 (grep/^all$/,@sections) { + @buildsections = sort {$a cmp $b} keys(%sectioncount); + } else { + @buildsections = @sections; } } - &build_members_list($cdom,$cnum,\@types,\@roles, - \@sections,\%users,\%userdata); + } + + if (($state eq 'pick_members') || ($state eq 'pick_privs') || ($state eq 'change_privs')) { + &build_members_list($cdom,$cnum,\@types,\@roles,\@buildsections,\%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 ++; + 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 ($env{'form.granularity'} eq 'Yes') { - $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox'; + if ($granularity eq 'Yes') { + $elements{$action}{'change_members'}{'user_'.$tool} = 'checkbox'; } } - $elements{'create'}{'pick_members'}{'specificity'} = 'radio'; + if ($specificity eq 'Yes') { + $elements{$action}{'change_members'}{'changepriv'} = 'checkbox'; + } } } - if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') && - ($env{'form.specificity'} eq 'No')))) { + 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 (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) { - foreach my $member (@members) { - foreach my $tool (keys(%{$usertools{$member}})) { - foreach my $priv (keys(%{$toolprivs{$tool}})) { - unless (exists($fixedprivs{$tool}{$priv})) { - $elements{'create'}{'pick_privs'}{'userpriv_'.$priv} = - 'checkbox'; + } + + 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}} = (); } } } } } } - - my $jscript; - if ($env{'form.action'} eq 'create') { - $jscript = &Apache::loncommon::check_uncheck_jscript(); + + 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'; + } + } + } + } + } + + if (($action eq 'create' && $state eq 'pick_name') || + ($action eq 'modify' && $state eq 'change_settings')) { + my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,\%stored); + my $space_trim = '/^\s*|\s*\$/g,""'; + my $float_check = '/^([0-9]*\.?[0-9]*)$/'; + $validate_script = ' + var newquota = new String(document.'.$state.'.quota.value); + newquota.replace('.$space_trim.'); + if (newquota == "" ) { + document.'.$state.'.quota.value = 0; + newquota = "0"; + } + var maxposs = '.sprintf("%.2f",$maxposs).'; + if (newquota > maxposs) { + alert("The file repository quota you entered for this group ("+newquota+" Mb) exceeds the maximum possible ("+maxposs+" Mb). Please enter a smaller number."); + return; + } + var re_quota = '.$float_check.'; + var check_quota = newquota.match(re_quota); + if (check_quota == null) { + alert("The quota you entered contains invalid characters, the quota should only include numbers, with or without a decimal point."); + return; } + if (newquota == 0) { + var warn_zero = 0; + for (var i=0; iprint(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'), - $jscript,$action,$state,$function,$loaditems)); + $r->print(&header("Groups Manager", + $jscript,$action,$state,$page,$loaditems)); if ($env{'form.refpage'} eq 'enrl') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/dropadd", text=>"Enrollment Manager", faq=>9,bug=>'Instructor Interface',}); - } else { + if ($action eq 'modify' || $action eq 'delete') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/coursegroups?refpage=enrl&action=$action", + text=>"Groups", + faq=>9,bug=>'Instructor Interface',}); + } + } else { &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/coursegroups", - text=>"Course Groups", - faq=>9,bug=>'Instructor Interface',}); + ({href=>"/adm/coursegroups", + text=>"Groups", + faq=>9,bug=>'Instructor Interface',}); + if ($env{'form.refpage'} eq 'grouplist') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/$cdom/$cnum/$env{'form.groupname'}/smppg?ref=grouplist", + text=>"Group: $description",}); + } } - my %states = (); - @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result'); - @{$states{'modify'}} = (); - my %trail = (); - %{$trail{'create'}} = ( - pick_name => 'Group Settings', + %{$trail{'create'}} = &Apache::lonlocal::texthash ( + pick_name => $ucgpterm.' Settings', pick_members => 'Select Members', pick_privs => 'Choose Privileges', result => 'Creation Complete', ); - %{$trail{'modify'}} = (); - - if ((($action eq 'create') || ($action eq 'modify')) && + %{$trail{'modify'}} = &Apache::lonlocal::texthash( + pick_task => 'Choose Task', + change_settings => "$ucgpterm 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', + ); + %{$trail{'delete'}} = &Apache::lonlocal::texthash( + verify => 'Verify deletion', + result => 'Deletion Complete' + ); + my %navbuttons = &Apache::lonlocal::texthash( + gtns => 'Go to next step', + gtps => 'Go to previous step', + crgr => 'Create '.$gpterm, + mose => 'Modify settings', + gtpp => 'Go to previous page', + adme => 'Add members', + ); + if ((($action eq 'create') || ($action eq 'modify') || ($action eq 'delete')) && ($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 - (undef,'Course Groups Manager')); - &display_control($r,$cdom,$cnum,$tabcol,$action,$state, - \%sectioncount,$groupname,$description,$functions, - \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate, - \%users,\%userdata,$idx,\@members,\%usertools); + ("Groups Manager","Creating_Groups")); + &display_control($r,$cdom,$cnum,$action,$state,$page, + \%sectioncount,$groupname,$description,$functions, + \@tools,$toolprivs,$fixedprivs,$startdate,$enddate, + \%users,\%userdata,$idx,\%memchg,\%usertools, + $view_permission,$manage_permission, + \%stored,$granularity,$quota,$specificity,\@types,\@roles, + \@sections,\%states,\%navbuttons,$gpterm,$ucgpterm, + $crstype); last; } else { - if ($state eq 'result' && $i > 0) { - &Apache::lonhtmlcommon::add_breadcrumb( + if (($action eq 'create') || ($action eq 'modify')) { + 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( + } 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"}); + {text=>"View $gpterm".'s'}); $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,'Course Groups Manager')); - &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, - $view_permission,$manage_permission); - + ('Groups Manager')); + &display_groups($r,$cdom,$cnum,$functions,$idx,$view_permission, + $manage_permission,$action,$state,$gpterm,$ucgpterm, + $crstype); } $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'}; + $stored{'quota'} = $groupinfo{'quota'}; + + 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,$sectioncount,$groupname, + my ($r,$cdom,$cnum,$action,$state,$page,$sectioncount,$groupname, $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate, - $enddate,$users,$userdata,$idx,$members,$usertools) = @_; + $enddate,$users,$userdata,$idx,$memchg,$usertools, + $view_permission,$manage_permission,$stored,$granularity,$quota, + $specificity,$types,$roles,$sections,$states,$navbuttons, + $gpterm,$ucgpterm,$crstype) = @_; if ($action eq 'create') { if ($state eq 'pick_name') { - &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions, - $sectioncount); + &general_settings_form($r,$cdom,$cnum,$action,$state,$page, + $functions,$tools,$toolprivs,$fixedprivs, + $sectioncount,$stored,$states,$navbuttons, + $gpterm,$ucgpterm,$crstype); + } elsif ($state eq 'pick_members') { + &choose_members_form($r,$cdom,$cnum,$action,$state,$page, + $groupname,$description,$granularity,$quota, + $startdate,$enddate,$tools,$fixedprivs, + $toolprivs,$functions,$users,$userdata,$idx, + $stored,$states,$navbuttons,$gpterm,$ucgpterm, + $crstype); + } elsif ($state eq 'pick_privs') { + &choose_privs_form($r,$cdom,$cnum,$action,$state,$page, + $startdate,$enddate,$tools,$functions, + $toolprivs,$fixedprivs,$userdata,$usertools, + $idx,$states,$stored,$sectioncount,$navbuttons, + $gpterm,$ucgpterm,$crstype); + } elsif ($state eq 'result') { + &process_request($r,$cdom,$cnum,$action,$state,$page, + $groupname,$description,$specificity,$userdata, + $startdate,$enddate,$tools,$functions, + $toolprivs,$usertools,$idx,$types,$roles, + $sections,$states,$navbuttons,$memchg, + $sectioncount,$stored,$gpterm,$ucgpterm,$crstype); + } + } elsif ($action eq 'modify') { + my $groupname = $env{'form.groupname'}; + if ($state eq 'pick_task') { + &modify_menu($r,$groupname,$page,$gpterm); + } elsif ($state eq 'change_settings') { + &general_settings_form($r,$cdom,$cnum,$action,$state,$page, + $functions,$tools,$toolprivs,$fixedprivs, + $sectioncount,$stored,$states,$navbuttons, + $gpterm,$ucgpterm,$crstype); + } elsif ($state eq 'change_members') { + &change_members_form($r,$cdom,$cnum,$action,$state,$page, + $groupname,$description,$startdate,$enddate, + $tools,$fixedprivs,$functions,$users, + $userdata,$granularity,$quota,$specificity, + $idx,$states,$navbuttons,$gpterm,$ucgpterm); + } elsif ($state eq 'add_members') { + &add_members_form($r,$cdom,$cnum,$action,$state,$page,$startdate, + $enddate,$groupname,$description,$granularity, + $quota,$sectioncount,$tools,$functions,$stored, + $states,$navbuttons,$gpterm,$ucgpterm); } elsif ($state eq 'pick_members') { - &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname, - $description,$startdate,$enddate,$tools, - $functions,$users,$userdata,$idx); + &choose_members_form($r,$cdom,$cnum,$action,$state,$page, + $groupname,$description,$granularity,$quota, + $startdate,$enddate,$tools,$fixedprivs, + $toolprivs,$functions,$users,$userdata,$idx, + $stored,$states,$navbuttons,$gpterm,$ucgpterm, + $crstype); } elsif ($state eq 'pick_privs') { - &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate, - $enddate,$tools,$functions,$toolprivs,$fixedprivs, - $userdata,$members,$usertools,$idx); + &choose_privs_form($r,$cdom,$cnum,$action,$state,$page, + $startdate,$enddate,$tools,$functions, + $toolprivs,$fixedprivs,$userdata,$usertools, + $idx,$states,$stored,$sectioncount,$navbuttons, + $gpterm,$ucgpterm,$crstype); + } elsif ($state eq 'change_privs') { + &change_privs_form($r,$cdom,$cnum,$action,$state,$page, + $startdate,$enddate,$tools,$functions, + $toolprivs,$fixedprivs,$userdata,$usertools, + $memchg,$idx,$states,$stored,$sectioncount, + $navbuttons,$gpterm,$ucgpterm); + } elsif ($state eq 'chgresult' || $state eq 'memresult' || + $state eq 'addresult') { + &process_request($r,$cdom,$cnum,$action,$state,$page, + $groupname,$description,$specificity,$userdata, + $startdate,$enddate,$tools,$functions, + $toolprivs,$usertools,$idx,$types,$roles, + $sections,$states,$navbuttons,$memchg, + $sectioncount,$stored,$gpterm,$ucgpterm,$crstype); + } + } elsif ($action eq 'delete') { + my %stored = &retrieve_settings($cdom,$cnum,$groupname); + if ($state eq 'verify') { + &verify_delete($r,$groupname,$state,$action,$page,$states, + \%stored); } elsif ($state eq 'result') { - &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname, - $description,$userdata,$startdate,$enddate,$tools, - $functions,$toolprivs,$members,$usertools,$idx); + &delete_group($r,$cdom,$cnum,$groupname); + } + } +} + +sub verify_delete { + my ($r,$groupname,$formname,$action,$page,$states,$stored) = @_; + $r->print(&Apache::lonhtmlcommon::echo_form_input([])); + $r->print(&mt("You have requested deletion of the following group: ").''. + $stored->{'description'}.''. + '

'.&mt('When a group is deleted the following occurs:').'
    '. + '
  • '.&mt('All group membership is terminated.').'
  • '. + '
  • '.&mt('The group ceases to be available either for viewing or for modification of group settings and membership.').'
  • '. + '
  • '.&mt('The group folder is removed from the folder containing it - normally this is the "Course Groups" folder which contains folders for all groups in the course.').'
  • '. + '
'.&mt('Although a deleted group is no longer accessible, the group name used for the group will be reserved, and will not be available for assignment to a new group in the same course in the future.')); + my $prevtext = &mt('Go back'); + my $nexttext = &mt('Delete group'); + my $prev; + if ($env{'form.refpage'} eq 'enrl') { + $prev = 'view'; + } + &display_navbuttons($r,$formname,$prev,$prevtext, + $$states{$action}[$page+1],$nexttext); + return; +} + +sub delete_group { + my ($r,$cdom,$cnum,$groupname) = @_; + my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, + $groupname); + my $now = time; + my $num_users = 0; + my $num_fail = 0; + my $num_ok = 0; + my @deleted; + my @undeleted; + my %usersettings; + foreach my $key (sort(keys(%membership))) { + if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { + my $user = $1; + my($end,$start,@userprivs) = split(/:/,$membership{$key}); + if ($start != -1) { + $num_users ++; + $usersettings{$groupname.':'.$user} = $now.':-1:'; + if (&Apache::lonnet::modify_group_roles($cdom,$cnum, + $groupname,$user, + $now,'-1','') + eq 'ok') { + $num_ok ++; + push(@deleted,$user); + } else { + push(@undeleted,$user); + $num_fail ++; + } + } + } + } + if ($num_ok > 0) { + my $roster_result = + &Apache::lonnet::modify_coursegroup_membership($cdom,$cnum, + \%usersettings); + } + if ($num_fail > 0) { + $r->print(&mt('Group deletion failed because deletion of [_1] out of [_2] members failed',$num_fail,$num_users)); + + } else { + my ($result,$message) = + &Apache::lonnet::delete_coursegroup($cdom,$cnum,$groupname); + if ($result eq 'ok') { + my $outcome = &modify_folders($cdom,$cnum,$groupname); + if ($outcome eq '') { + $r->print(&mt('Group successfully deleted')); + } else { + $r->print(&mt("Although the group was deleted, an error ([_1]) occurred when removing the group's folder from the 'Course Groups' folder.",$outcome)); + } + } else { + $r->print(&mt('Group deletion failed')); + } + } + return; +} + +sub modify_folders { + my ($cdom,$cnum,$groupname) = @_; + my $outcome; + my $navmap = Apache::lonnavmaps::navmap->new(); + my $groupmap = '/uploaded/'.$cdom.'/'.$cnum.'/'.'group_folder_'. + $groupname.'.sequence'; + my $groupmapres = $navmap->getResourceByUrl($groupmap); + if ($groupmapres) { + my ($map,$id,$src)=&Apache::lonnet::decode_symb($groupmapres->symb()); + $map = '/'.$map; + my ($errtext,$fatal) = &LONCAPA::map::mapread($map); + if ($fatal) { + $outcome=&mt('Error reading contents of parent folder to group'). + " ($map): $errtext".'
'; + } else { + my $idx = 0; + my $grpidx; + foreach my $item (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$item]); + $url=&LONCAPA::map::qtescape($url); + if ($url eq $groupmap) { + $grpidx = $idx; + last; + } else { + $idx++; + } + } + + if ($grpidx ne '') { + &LONCAPA::map::makezombie($LONCAPA::map::order[$grpidx]); + for (my $i=$grpidx;$i<$#LONCAPA::map::order;$i++) { + $LONCAPA::map::order[$i] = $LONCAPA::map::order[$i+1]; + } + $#LONCAPA::map::order--; + my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1); + if ($outtext) { + $outcome = &mt('Error storing updated parent folder to group'). " ($map): $errtext".'
'; + return; + } + } } } + undef($navmap); + return $outcome; } sub header { - my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_; - my $html=&Apache::lonxml::xmlbegin(); - my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems); + my ($bodytitle,$jscript,$action,$state,$page,$loaditems) = @_; + my $start_page= + &Apache::loncommon::start_page($bodytitle, + '', + {'add_entries' => $loaditems,}); my $output = <<"END"; -$html - -$title - - -$bodytag -
+$start_page + END if ($action eq 'create' || $action eq 'modify') { @@ -531,6 +1229,7 @@ END + END } return $output; @@ -538,23 +1237,30 @@ END sub onload_action { my ($action,$state) = @_; - my $loaditems; + 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.')"'; + $loaditems{'onload'} = + 'javascript:setFormElements(document.'.$state.')'; } } - return $loaditems; + if (($action eq 'modify') && + ($state eq 'change_settings' || $state eq 'change_members' || + $state eq 'change_privs' || $state eq 'add_members')) { + $loaditems{'onload'} = + 'javascript:setFormElements(document.'.$state.')'; + } + return \%loaditems; } sub footer { + my $end_page = &Apache::loncommon::end_page(); return(< - - +$end_page ENDFOOT } @@ -568,11 +1274,26 @@ sub build_members_list { $access{$type} = $type; } &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles, - $sections,$users,$userdata); + $sections,$users,$userdata); return; } sub group_files { + my ($group,$currdir,$numfiles,$numdirs) = @_; + my $dirptr=16384; + my @dir_list=&Apache::portfolio::get_dir_list($currdir,$group); + foreach my $line (@dir_list) { + my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$line,16); + if (($filename !~ /^\.\.?$/) && ($filename !~ /\.meta$/ ) && ($filename !~ /(.*)\.(\d+)\.([^\.]*)$/) && ($filename ne 'no_such_dir')) { + if ($dirptr&$testdir) { + $currdir .= '/'.$filename; + $$numdirs ++; + &group_files($numfiles,$numdirs) + } else { + $$numfiles ++; + } + } + } return; } @@ -580,115 +1301,125 @@ 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 $now = time; + my %lt = &Apache::lonlocal::texthash ( + active => 'active', + previous => 'previous', + future => 'future', + ); + my %membercounts = ( + active => 0, + previous => 0, + future => 0, + ); my $totalmembers = 0; - my $active = 0; - my $previous = 0; - my $future = 0; foreach my $member (keys %memberhash) { $totalmembers ++; my ($end,$start) = split(/:/,$memberhash{$member}); - if (($end!=0) && ($end<$now)) { - $previous ++; - } elsif (($start!=0) && ($start>$now)) { - $future ++; - } else { - $active ++; + unless ($start == -1) { + if (($end!=0) && ($end<$now)) { + $membercounts{previous} ++; + } elsif (($start!=0) && ($start>$now)) { + $membercounts{future} ++; + } else { + $membercounts{active} ++; + } } } if ($totalmembers == 0) { $$group_info{$group}{'totalmembers'} = 'None'; } else { - $$group_info{$group}{'totalmembers'} = $active.' - active
'.$previous.' -previous
'.$future.' -future'; + foreach my $type ('active','previous','future') { + $$group_info{$group}{'totalmembers'} .= + &open_list_window($group,$type,$membercounts{$type},$lt{$type}); + } } return 'ok'; } +sub open_list_window { + my ($group,$status,$count,$text) = @_; + my $entry; + if ($count > 0) { + $entry = ''.$text.' - '.$count. + '
'; + } else { + $entry = ''.$text.' - '.$count.'
'; + } + return $entry; +} -sub first_creation_form { - my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_; - my %lt = &Apache::lonlocal::texthash( - 'gmem' => 'Group membership options', - 'picr' => 'Pick the criteria to use to build a list of course users '. - 'from which you will select members of the new group', - 'gdat' => 'Group open and close dates', - 'sten' => 'Set a start date/time and end date/time for the group', - 'acty' => 'Access types', - 'coro' => 'Course roles', - 'cose' => 'Course sections', - 'gfun' => 'Group functionality', - ); - - 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 $starttime = time; - my $endtime = time+(6*30*24*60*60); # 6 months from now, approx - my ($start_table,$end_table) = &date_setting_table - ($starttime,$endtime,$formname); - - my @sections = (); - my $section_sel = ''; - my $numvisible = 4; +sub general_settings_form { + my ($r,$cdom,$cnum,$action,$formname,$page,$functions,$tools, + $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons, + $gpterm,$ucgpterm,$crstype) = @_; + my ($nexttext,$prevtext); + &groupsettings_options($r,$functions,$action,$formname,$stored,1, + $gpterm,$ucgpterm,$crstype); + &access_date_settings($r,$action,$formname,$stored,2,$gpterm,$ucgpterm); + if ($action eq 'create') { + &membership_options($r,$cdom,$cnum,$action,$formname,$sectioncount,3, + $gpterm,$ucgpterm); + $nexttext = $$navbuttons{'gtns'}; + } else { + my @available = (); + my @unavailable = (); + &check_tools($functions,$tools,\@available,\@unavailable); + @{$tools} = sort(keys(%{$functions})); + &privilege_specificity($r,$action,3,$tools,$stored,$toolprivs, + $fixedprivs,\@available,$formname, + $gpterm,$ucgpterm); + &mapping_options($r,$action,$formname,$page,$sectioncount, + $states,$stored,$navbuttons,4,5, + $gpterm,$ucgpterm,$crstype,$cdom,$cnum); + $nexttext = $$navbuttons{'mose'}; + } + $prevtext = $$navbuttons{'gtpp'}; + &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, + $$states{$action}[$page+1],$nexttext); + return; +} - @sections = sort {$a cmp $b} keys(%{$sectioncount}); - if (@sections > 0) { - unshift(@sections,'_all'); # Put 'all' at the front of the list - if (@sections < 4) { - $numvisible = @sections; - } - foreach (@sections) { - if ($_ eq '_all') { - $section_sel .= '