--- loncom/interface/loncoursegroups.pm 2006/03/21 18:32:59 1.10 +++ loncom/interface/loncoursegroups.pm 2006/07/04 20:50:52 1.37 @@ -1,3 +1,6 @@ +# The LearningOnline Network with CAPA +# +# $Id: loncoursegroups.pm,v 1.37 2006/07/04 20:50:52 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,14 +33,18 @@ use Apache::loncommon; use Apache::lonhtmlcommon; use Apache::lonlocal; use Apache::lonnavmaps; +use Apache::longroup; +use Apache::portfolio; 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; } @@ -63,13 +70,18 @@ sub handler { &Apache::lonnet::allowed('mdg',$env{'request.course.id'}); &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 = (); @@ -77,63 +89,78 @@ 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 $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,$cdom,$cnum,$function,$tabcol, - \%functions,\%idx,$view_permission, - $manage_permission,$rowColor1,$rowColor2); + &group_administration($r,$action,$state,$cdom,$cnum,$function, + $tabcol,\%functions,\%idx,$view_permission, + $manage_permission,$rowColor1,$rowColor2, + $gpterm,$ucgpterm,$crstype); } else { - $r->print(&mt('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,$action, - $rowColor1,$rowColor2); + $view_permission,$manage_permission,$action,$state, + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); } return OK; } sub print_main_menu { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, - $manage_permission,$action,$rowColor1,$rowColor2) = @_; - $r->print(&header('Course Groups',undef,undef,undef,undef,$function)); + $manage_permission,$action,$state,$rowColor1,$rowColor2,$gpterm, + $ucgpterm,$crstype) = @_; + my $pagename = "$crstype $ucgpterm".'s'; + my $jscript = qq| +function changeSort(caller) { + document.$state.sortby.value = caller; + document.$state.submit(); +}\n|; + $r->print(&header($pagename,$jscript,$action,$state, + undef,$function)); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", - text=>"Course Groups",}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,'Course Groups')); + text=>"$pagename"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs($pagename)); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, - $view_permission,$manage_permission,$action,$rowColor1, - $rowColor2); + $view_permission,$manage_permission,$action,$state, + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); $r->print(&footer()); return; } sub display_groups { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, - $manage_permission,$action,$rowColor1,$rowColor2) = @_; + $manage_permission,$action,$state,$rowColor1,$rowColor2,$gpterm, + $ucgpterm,$crstype) = @_; my %curr_groups = (); my %grp_info = (); - my %actionlinks = ( - modify => ' 'View', delete => 'Delete', act => 'Action', - gname => 'Group Name', + gname => "$ucgpterm Name", desc => 'Description', crea => 'Creator', crtd => 'Created', @@ -143,20 +170,23 @@ sub display_groups { memb => 'Members', file => 'Files', dibd => 'Discussion Boards', - dius => 'Disk Use', - nogr => 'No groups exist.', - crng => 'Create a new group', + dius => 'Disk Use (%)', + nogr => 'No '.$gpterm.'s exist.', + crng => 'Create a new '.$gpterm, alth => 'Although your current role has privileges'. - ' to view any existing groups in this course,'. - ' you do not have privileges to create new'. - ' groups.', + ' to view any existing '.$gpterm.'s in this'. + lc($crstype).', you do not have privileges'. + 'to create new '.$gpterm.'s.', ); if ($view_permission) { if (!defined($action)) { $action = 'view'; } - my %curr_groups; - if (&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum)) { + my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum); + if (%curr_groups) { + if ($manage_permission) { + $r->print('
'.$lt{'crng'}.''); + } $r->print('

'); $r->print(&Apache::lonhtmlcommon::start_pick_box()); $r->print(<<"END"); @@ -174,7 +204,7 @@ sub display_groups { $lt{'func'} $lt{'quot'} - $lt{'memb'} + $lt{'memb'} $lt{'file'} $lt{'dibd'} $lt{'dius'} @@ -183,16 +213,31 @@ END 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 $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') { @@ -224,13 +269,14 @@ END $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; @@ -246,21 +292,37 @@ END if ($action eq 'modify' || $action eq 'delete') { $link .= $group; } else { - $link .= $group.'/grppg?register=1'; + $link .= $group.'/grppg'; + } + $link .= '">'.$lt{$action}.''; + if ($action eq 'view') { + if (($manage_permission) && + ($env{'form.refpage'} ne 'enrl')) { + $link .= '  '.$actionlinks{'modify'}. + $group.'">'.$lt{'modify'}.''; + } } - $link .= '">'.$lt{$action}.''; - $r->print(''.$link.''.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.$totalfiles.''.$boards.''.$diskuse.''); + $r->print(''.$link.''.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.&mt('Files: ').$totalfiles.'
'.&mt('Folders: ').$totaldirs.'
'.$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'}); + $r->print('

'.$lt{'alth'}); } } @@ -268,28 +330,30 @@ END my @coursegroups = split(/:/,$env{'request.course.groups'}); if (@coursegroups > 0) { $r->print('

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

'); + $r->print(''.$group,'
'.$description.'

'); } } } else { $r->print(&mt('You are not currently a member of any '. - 'active groups in this course')); + '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,$rowColor1,$rowColor2) = @_; + my ($r,$action,$state,$cdom,$cnum,$function,$tabcol,$functions,$idx, + $view_permission,$manage_permission,$rowColor1,$rowColor2,$gpterm, + $ucgpterm,$crstype) = @_; my %sectioncount = (); my @tools = (); my @types = (); @@ -303,8 +367,8 @@ sub group_administration { my %memchg; my @member_changes = ('deletion','expire','activate','reenable', 'changefunc','changepriv'); - my $state = $env{'form.state'}; - my ($groupname,$description,$startdate,$enddate,$granularity,$specificity); + my ($groupname,$description,$startdate,$enddate,$granularity,$specificity, + $quota,$validate_script); if (defined($env{'form.groupname'})) { $groupname = $env{'form.groupname'}; @@ -328,7 +392,9 @@ sub group_administration { 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')))) { @@ -342,7 +408,11 @@ sub group_administration { if ($action eq 'modify') { if ($state eq '') { - $state = 'pick_group'; + 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') { @@ -363,89 +433,68 @@ sub group_administration { $description = $stored{'description'}; $granularity = $stored{'granularity'}; $specificity = $stored{'specificity'}; + $quota = $stored{'quota'}; } } } - 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', - 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{'modify'}{'change_settings'}} = ( - %{$elements{'create'}{'pick_name'}}, - specificity => 'radio', - defpriv => 'checkbox', - autorole => 'checkbox', - autoadd => 'radio', - autodrop => 'radio', - ); + 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'}}) { - $elements{'modify'}{'change_settings'}{'sec_'.$role} = 'selectbox'; + unless ($role eq 'cc') { + $elements{'modify'}{'change_settings'}{'sec_'.$role} = + 'selectbox'; + } } } - %{$elements{'create'}{'pick_members'}} = ( - member => 'checkbox', - defpriv => 'checkbox', - ); - - %{$elements{'modify'}{'add_members'}} = ( - types => 'selectbox', - roles => 'selectbox', - ); if (($action eq 'create') && ($state eq 'pick_name')) { $elements{'create'}{'pick_name'}{'types'} = 'selectbox'; @@ -455,16 +504,16 @@ sub group_administration { (($state eq 'pick_name') || ($state eq 'pick_privs'))) || (($action eq 'modify') && (($state eq 'change_settings') || ($state eq 'add_members')))) { - my $numsections = &Apache::loncommon::get_sections($cdom,$cnum, - \%sectioncount); - if ($numsections > 0) { + %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') { + if (($action eq 'create') || + ($action eq 'modify' && $state eq 'pick_members')) { if (defined($env{'form.types'})) { @types=&Apache::loncommon::get_env_multiple('form.types'); } @@ -473,7 +522,7 @@ sub group_administration { } if (defined($env{'form.sectionpick'})) { @sections=&Apache::loncommon::get_env_multiple('form.sectionpick'); - if (grep/^_all$/,@sections) { + if (grep/^all$/,@sections) { @sections = sort {$a cmp $b} keys(%sectioncount); } } @@ -557,11 +606,17 @@ sub group_administration { } if (($state eq 'pick_privs') || ($state eq 'change_privs') || - (($specificity eq 'No') && - (($state eq 'result') || ($state eq 'memresult')))) { + (($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; } @@ -593,8 +648,8 @@ sub group_administration { } my @currtools = (); if (@userprivs > 0) { - foreach my $tool (sort(keys(%fixedprivs))) { - foreach my $priv (keys(%{$fixedprivs{$tool}})) { + foreach my $tool (sort(keys(%{$fixedprivs}))) { + foreach my $priv (keys(%{$$fixedprivs{$tool}})) { if (grep/^$priv$/,@userprivs) { push(@currtools,$tool); last; @@ -664,19 +719,59 @@ sub group_administration { && ($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})) { + 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 = document.'.$state.'.quota.value; + newquota.replace('.$space_trim.'); + if (newquota == "" ) { + document.'.$state.'.quota.value = 0; + newquota = 0; + } + var maxposs = '.$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', + my $crumbtitle = "$crstype $ucgpterm".'s'; + $r->print(&header("$crumbtitle Manager", $jscript,$action,$state,$page,$function,$loaditems)); if ($env{'form.refpage'} eq 'enrl') { @@ -731,21 +827,21 @@ function changeSort(caller) { } else { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", - text=>"Course Groups", + text=>"$crumbtitle", faq=>9,bug=>'Instructor Interface',}); } my %trail = (); %{$trail{'create'}} = &Apache::lonlocal::texthash ( - pick_name => 'Group Settings', + pick_name => $ucgpterm.' Settings', pick_members => 'Select Members', pick_privs => 'Choose Privileges', result => 'Creation Complete', ); %{$trail{'modify'}} = &Apache::lonlocal::texthash( - pick_group => 'Groups', + pick_group => $ucgpterm.'s', pick_task => 'Choose Task', - change_settings => 'Group Settings', + change_settings => "$ucgpterm Settings", change_members => 'Modify/Delete Members', change_privs => 'Change Privileges', change_mapping => 'Membership Mapping', @@ -759,7 +855,7 @@ function changeSort(caller) { my %navbuttons = &Apache::lonlocal::texthash( gtns => 'Go to next step', gtps => 'Go to previous step', - crgr => 'Create group', + crgr => 'Create '.$gpterm, mose => 'Modify settings', gtpp => 'Go to previous page', adme => 'Add members', @@ -771,14 +867,15 @@ function changeSort(caller) { &Apache::lonhtmlcommon::add_breadcrumb( {text=>"$trail{$action}{$state}"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,'Course Groups Manager')); + ("$crumbtitle Manager")); &display_control($r,$cdom,$cnum,$tabcol,$action,$state,$page, \%sectioncount,$groupname,$description,$functions, - \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate, + \@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); + \%stored,$granularity,$quota,$specificity,\@types,\@roles, + \@sections,\%states,\%navbuttons,$rowColor1,$rowColor2, + $gpterm,$ucgpterm,$crstype); last; } else { if (($state eq 'result') && ($i > 0)) { @@ -794,12 +891,13 @@ function changeSort(caller) { } } elsif (($action eq 'view') && ($view_permission)) { &Apache::lonhtmlcommon::add_breadcrumb( - {text=>"View groups"}); + {text=>"View $gpterm".'s'}); + my $crumbtitle = "$crstype $ucgpterm".'s Manager'; $r->print(&Apache::lonhtmlcommon::breadcrumbs - (undef,'Course Groups Manager')); + (&mt($crumbtitle))); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, - $view_permission,$manage_permission,$action, - $rowColor1,$rowColor2); + $view_permission,$manage_permission,$action,$state, + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); } $r->print(&footer()); @@ -808,55 +906,58 @@ function changeSort(caller) { sub retrieve_settings { my ($cdom,$cnum,$groupname) = @_; - my %groupinfo; + 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; - my %curr_groups; - my $numgroups = &Apache::loncommon::coursegroups(\%curr_groups,$cdom, - $cnum,$groupname); - if ($numgroups > 0) { - %groupinfo = &Apache::loncommon::get_group_settings( - $curr_groups{$groupname}); - $stored{'description'} = &Apache::lonnet::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'}}))) { - foreach my $section (@{$groupinfo{'autosec'}{$role}}) { - push (@{$stored{'sec_'.$role}},$section); - } - if (@{$groupinfo{'autosec'}{$role}} > 0) { - push(@{$stored{'autorole'}},$role); - } + + $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; } @@ -865,78 +966,86 @@ 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)=@_; + $view_permission,$manage_permission,$stored,$granularity,$quota, + $specificity,$types,$roles,$sections,$states,$navbuttons,$rowColor1, + $rowColor2,$gpterm,$ucgpterm,$crstype) = @_; 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); + $rowColor1,$rowColor2,$gpterm,$ucgpterm, + $crstype); } elsif ($state eq 'pick_members') { &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, - $groupname,$description,$granularity, + $groupname,$description,$granularity,$quota, $startdate,$enddate,$tools,$fixedprivs, $toolprivs,$functions,$users,$userdata,$idx, $stored,$states,$navbuttons,$rowColor1, - $rowColor2); + $rowColor2,$gpterm,$ucgpterm,$crstype); } 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); + $rowColor1,$rowColor2,$gpterm,$ucgpterm, + $crstype); } 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); + $sectioncount,$stored,$rowColor1,$rowColor2, + $gpterm,$ucgpterm,$crstype); } } 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, - $rowColor1,$rowColor2); + $view_permission,$manage_permission,$action,$state, + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); } elsif ($state eq 'pick_task') { - &modify_menu($r,$groupname,$page); + &modify_menu($r,$groupname,$page,$gpterm); } 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); + $rowColor1,$rowColor2,$gpterm,$ucgpterm, + $crstype); } 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); + $userdata,$granularity,$quota,$specificity, + $idx,$states,$navbuttons,$rowColor1,$rowColor2, + $gpterm,$ucgpterm); } 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); + $quota,$sectioncount,$tools,$functions,$stored, + $states,$navbuttons,$rowColor1,$rowColor2,$gpterm, + $ucgpterm); } elsif ($state eq 'pick_members') { &choose_members_form($r,$cdom,$cnum,$tabcol,$action,$state,$page, - $groupname,$description,$granularity, + $groupname,$description,$granularity,$quota, $startdate,$enddate,$tools,$fixedprivs, $toolprivs,$functions,$users,$userdata,$idx, $stored,$states,$navbuttons,$rowColor1, - $rowColor2); + $rowColor2,$gpterm,$ucgpterm,$crstype); } 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); + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); } 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); + $navbuttons,$rowColor1,$rowColor2,$gpterm, + $ucgpterm); } elsif ($state eq 'chgresult' || $state eq 'memresult' || $state eq 'addresult') { &process_request($r,$cdom,$cnum,$tabcol,$action,$state,$page, @@ -944,7 +1053,8 @@ sub display_control { $startdate,$enddate,$tools,$functions, $toolprivs,$usertools,$idx,$types,$roles, $sections,$states,$navbuttons,$memchg, - $sectioncount,$stored,$rowColor1,$rowColor2); + $sectioncount,$stored,$rowColor1,$rowColor2, + $gpterm,$ucgpterm,$crstype); } } } @@ -952,11 +1062,13 @@ sub display_control { sub header { my ($bodytitle,$jscript,$action,$state,$page,$function,$loaditems) = @_; my $start_page= - &Apache::loncommon::start_page($bodytitle,$jscript, + &Apache::loncommon::start_page($bodytitle, + '', {'function' => $function, 'add_entries' => $loaditems,}); my $output = <<"END"; -$bodytag +$start_page
END @@ -973,23 +1085,23 @@ 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.')'; } } 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.')"'; + $loaditems{'onload'} = + 'javascript:setFormElements(document.'.$state.')'; } - return $loaditems; + return \%loaditems; } sub footer { @@ -1016,6 +1128,21 @@ sub build_members_list { } 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; } @@ -1028,7 +1155,6 @@ sub group_members { $$group_info{'totalmembers'} = 'Unknown - an error occurred'; return $tmp; } - my $now = time; my $totalmembers = 0; my $active = 0; my $previous = 0; @@ -1058,23 +1184,26 @@ sub group_members { sub general_settings_form { my ($r,$cdom,$cnum,$action,$tabcol,$formname,$page,$functions,$tools, $toolprivs,$fixedprivs,$sectioncount,$stored,$states,$navbuttons, - $rowColor1,$rowColor2) = @_; + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype) = @_; my ($nexttext,$prevtext); $r->print('
'); - &groupsettings_options($r,$tabcol,$functions,$action,$formname,$stored,1); + &groupsettings_options($r,$tabcol,$functions,$action,$formname,$stored,1, + $gpterm,$ucgpterm,$crstype); $r->print(' '); - &access_date_settings($r,$tabcol,$action,$formname,$stored,2); + &access_date_settings($r,$tabcol,$action,$formname,$stored,2,$gpterm, + $ucgpterm); $r->print(' '); if ($action eq 'create') { - &membership_options($r,$action,$formname,$tabcol,$sectioncount,3); + &membership_options($r,$action,$formname,$tabcol,$sectioncount,3, + $gpterm,$ucgpterm); $nexttext = $$navbuttons{'gtns'}; } else { my @available = (); @@ -1083,14 +1212,14 @@ sub general_settings_form { @{$tools} = sort(keys(%{$functions})); &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action, 3,$tools,$stored,$toolprivs,$fixedprivs, - \@available,$formname); + \@available,$formname,$gpterm,$ucgpterm); $r->print(' '); &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount, $states,$stored,$navbuttons,4,5,$rowColor1, - $rowColor2); + $rowColor2,$gpterm,$ucgpterm,$crstype); $nexttext = $$navbuttons{'mose'}; } $prevtext = $$navbuttons{'gtpp'}; @@ -1102,18 +1231,20 @@ sub general_settings_form { } sub groupsettings_options { - my ($r,$tabcol,$functions,$action,$formname,$stored,$image) = @_; + my ($r,$tabcol,$functions,$action,$formname,$stored,$image,$gpterm, + $ucgpterm,$crstype) = @_; 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', + 'gdat' => "$ucgpterm open and close dates", + 'sten' => "Set a start date/time and end date/time for the $gpterm", + 'gfun' => "$ucgpterm functionality", + 'gnde' => "$ucgpterm name, description and available functionality", 'desc' => 'Description', 'func' => 'Functionality', - 'gnam' => 'Group Name', - 'doyo' => 'Do you want to assign different functionality '. - 'to different group members?', + 'gnam' => "$ucgpterm Name", + 'doyo' => "Do you want to assign different functionality ". + "to different $gpterm members?", ); + my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored); &topic_bar($r,$tabcol,$image,$lt{'gnde'}); $r->print(' @@ -1174,8 +1305,8 @@ END - - + + + +
 
 
 
Granularity:'.$lt{'doyo'}.'  '); + '.&mt('Granularity:').''.$lt{'doyo'}.'  '); if ($action eq 'modify') { $r->print('  ('.&mt('Currently set to "[_1]"', $$stored{'granularity'}).')'); @@ -1183,6 +1314,30 @@ END $r->print('
'.&mt('Disk quota: ').''); + if ($action eq 'create') { + $r->print(&mt('If you enable the file repository for the [_1], allocate a disk quota.',$gpterm)); + } else { + $r->print(&mt('Quota allocated to file repository:')); + } + $r->print(' Mb'); + if ($action eq 'create') { + $r->print('
'. + &mt('A total of [_1] Mb is shared between all [_2]s in the '. + '[_3], and [_4] Mb are currently unallocated.',$crsquota, + $gpterm,lc($crstype),$freespace)); + } else { + $r->print('  ('.&mt('The quota is currently [_1] Mb', + $$stored{'quota'}).').'); + + $r->print('
'.&mt('The quota can be increased to [_1] Mb, '. + 'by adding all unallocated space for [_2]s in the [_3].', + $maxposs,$gpterm,lc($crstype))); + } + $r->print(' +
@@ -1190,28 +1345,47 @@ END return; } +sub get_quota_constraints { + my ($action,$stored) = @_; + my ($crsquota,$freespace,$maxposs); + $crsquota = $env{'course.'.$env{'request.course.id'}.'.internal.coursequota'}; + if ($crsquota eq '') { + $crsquota = 20; + } + $freespace = $crsquota - &Apache::longroup::sum_quotas(); + if ($action eq 'create') { + $maxposs = $freespace; + } else { + $maxposs = $$stored{'quota'} + $freespace; + } + return ($crsquota,$freespace,$maxposs); +} + sub membership_options { - my ($r,$action,$state,$tabcol,$sectioncount,$image) = @_; + my ($r,$action,$state,$tabcol,$sectioncount,$image,$gpterm,$ucgpterm) = @_; + my $crstype = &Apache::loncommon::course_type(); my %lt = &Apache::lonlocal::texthash( 'pipa' => 'Pick parameters to generate membership list', - 'gmem' => 'Group membership options', + 'gmem' => "$ucgpterm 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', + lc($crstype).' users from which you will select ', + 'meof' => "members of the new $gpterm.", + 'admg' => "additional members of the $gpterm.", + 'ifno' => "If you do not wish to add members when you first ". + "create the $gpterm, do not make any selections.", + 'asub' => "A subsequent step will also allow you to specify automatic adding/dropping of $gpterm members triggered by specified role and section changes.", 'acty' => 'Access types', - 'coro' => 'Course roles', - 'cose' => 'Course sections', + 'coro' => $crstype.' roles', + 'cose' => $crstype.' 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'); + + #FIXME need to plumb around for the various cr roles defined by the user + my @roles = ('st','cc','in','ta','ep'); my @sections = keys(%{$sectioncount}); @@ -1222,7 +1396,7 @@ sub membership_options { '.$lt{'gmem'}.'
'.$lt{'picr'}); if ($action eq 'create') { - $r->print($lt{'meof'}.'
'.$lt{'ifno'}); + $r->print($lt{'meof'}.'
'.$lt{'ifno'}.'
'.$lt{'asub'}); } else { $r->print($lt{'admg'}); } @@ -1246,8 +1420,8 @@ sub membership_options { $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,'_nosec'); # Put 'no sections' next + unshift(@sections,'none'); # Put 'no sections' next + unshift(@sections,'all'); # Put 'all' at the front of the list $r->print('  '. §ions_selection(\@sections,'sectionpick').''); @@ -1268,12 +1442,12 @@ sub sections_selection { $numvisible = @{$sections}; } foreach my $sec (@{$sections}) { - if ($sec eq '_all') { - $section_sel .= ' '."\n"; + } elsif ($sec eq 'none') { + $section_sel .= ' '."\n"; } else { - $section_sel .= ' \n"; } } my $output = ' @@ -1284,9 +1458,9 @@ sub sections_selection { } sub access_date_settings { - my ($r,$tabcol,$action,$formname,$stored,$image) = @_; + my ($r,$tabcol,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( - 'sten' => 'Default start and end dates for group access', + 'sten' => "Default start and end dates for $gpterm access", ); my $starttime = time; my $endtime = time+(6*30*24*60*60); # 6 months from now, approx @@ -1316,16 +1490,17 @@ sub access_date_settings { sub choose_members_form { my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description, - $granularity,$startdate,$enddate,$tools,$fixedprivs,$toolprivs, + $granularity,$quota,$startdate,$enddate,$tools,$fixedprivs,$toolprivs, $functions,$users,$userdata,$idx,$stored,$states,$navbuttons, - $rowColor1,$rowColor2) = @_; + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype) = @_; my @regexps = ('user_','userpriv_','sec_'); my %origmembers; $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','member','specificity','branch', 'defpriv','autorole','autoadd','autodrop','sortby','togglefunc'], \@regexps)); - my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum); + my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm, + $ucgpterm,$crstype); $r->print(' @@ -1346,8 +1521,8 @@ sub choose_members_form { if ($action eq 'create') { &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2, $functions,$startdate,$enddate,$groupname, - $description,$granularity,\@available, - \@unavailable); + $description,$granularity,$quota,\@available, + \@unavailable,$gpterm,$ucgpterm); $specimg = 4; $memimg = 5; } else { @@ -1369,11 +1544,11 @@ sub choose_members_form { } &privilege_specificity($r,$tabcol,$rowColor1,$rowColor2,$action, $specimg,$tools,$stored,$toolprivs, - $fixedprivs,\@available,$formname); + $fixedprivs,\@available,$formname,$gpterm,$ucgpterm); my $newusers = &pick_new_members($r,$action,$formname,$tabcol,$rowColor1, $rowColor2,\@available,$idx,$stored, $memimg,$users,$userdata,$granularity, - \%origmembers); + \%origmembers,$gpterm,$ucgpterm); if ($newusers || $action eq 'create') { &display_navbuttons($r,$formname,$$states{$action}[$page-1], $$navbuttons{'gtps'},$$states{$action}[$page+1], @@ -1426,17 +1601,19 @@ sub check_tools { sub print_current_settings { my ($r,$action,$tabcol,$rowColor1,$rowColor2,$functions,$startdate,$enddate, - $groupname,$description,$granularity,$available,$unavailable) =@_; + $groupname,$description,$granularity,$quota,$available,$unavailable, + $gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( - grna => 'Group Name', + grna => "$ucgpterm Name", desc => 'Description', - grfn => 'Group Functions', + grfn => "$ucgpterm Functions", gran => 'Granularity', + quot => 'File quota', dfac => 'Default access dates', - ygrs => 'Your group selections', - tfwa => 'The following settings will apply to the group:', - difn => 'Different functionality
for different users:', + ygrs => "Your $gpterm selections", + tfwa => "The following settings will apply to the $gpterm:", + difn => 'Different functionality
for different members:', stda => 'Start date', enda => 'End date:', ); @@ -1467,6 +1644,7 @@ sub print_current_settings { + @@ -1513,7 +1691,8 @@ sub print_current_settings { $r->print(<<"END"); + @@ -1529,16 +1708,17 @@ END sub pick_new_members { my ($r,$action,$formname,$tabcol,$rowColor1,$rowColor2,$available,$idx, - $stored,$img,$users,$userdata,$granularity,$origmembers) = @_; + $stored,$img,$users,$userdata,$granularity,$origmembers,$gpterm, + $ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( - 'gpme' => 'Group membership', + 'gpme' => "$ucgpterm membership", 'addm' => 'Add members', 'setf' => 'Set functionality', 'func' => 'Functionality', 'nome' => 'No members to add at this time.', - 'nnew' => 'There are no users to add as new members, as all users'. - ' matching the specified type(s), role(s), and/or '. - 'section(s) are already affiliated with this group.', + 'nnew' => "There are no users to add as new members, as all users". + " matching the specified type(s), role(s), and/or ". + "section(s) are already affiliated with this $gpterm.", 'yoma' => 'You may need to use the '."'".'modify existing, past or '. 'future members'."'".' page if you need to re-enable '. 'or activate access for previous or future members.', @@ -1604,6 +1784,7 @@ sub pick_new_members { + '); if (@{$available} > 0) { $r->print(''); @@ -1612,7 +1793,7 @@ sub pick_new_members { if (@{$available} > 0) { if ($granularity eq 'Yes') { $r->print(' - + '); + $udom.''. + ''); if (@{$available} > 0) { $r->print(''); &topic_bar($r,$tabcol,2,$lt{'mogm'}); @@ -2054,113 +2240,33 @@ sub current_membership { 'curf' => 'Current Functionality', 'chpr' => 'Change Privileges' ); - if (keys(%membership) > 0) { - my %current = (); - my %allnames = (); - my $hastools = 0; - my $addtools = 0; - my $num_reenable = 0; - my $num_activate = 0; - my $num_expire - 0; - foreach my $key (sort(keys(%membership))) { - if ($key =~ /^\Q$groupname\E:([^:]+):([^:]+)$/) { - my $uname = $1; - my $udom = $2; - my $user = $uname.':'.$udom; - my($end,$start,@userprivs) = split(/:/,$membership{$key}); - unless ($start == -1) { - $allnames{$udom}{$uname} = 1; - %{$current{$user}} = (); - $current{$user}{uname} = $uname; - $current{$user}{udom} = $udom; - $current{$user}{start} = - &Apache::lonlocal::locallocaltime($start); - if ($end == 0) { - $current{$user}{end} = 'No end date'; - } else { - $current{$user}{end} = - &Apache::lonlocal::locallocaltime($end); - } - my $now = time; - if (($end > 0) && ($end < $now)) { - $current{$user}{changestate} = 'reenable'; - $num_reenable++; - } elsif (($start > $now)) { - $current{$user}{changestate} = 'activate'; - $num_activate ++; - } else { - $current{$user}{changestate} = 'expire'; - $num_expire ++; - } - @{$current{$user}{currtools}} = (); - @{$current{$user}{newtools}} = (); - if (@userprivs > 0) { - foreach my $tool (sort(keys(%{$fixedprivs}))) { - foreach my $priv (keys(%{$$fixedprivs{$tool}})) { - if (grep/^$priv$/,@userprivs) { - push(@{$current{$user}{currtools}},$tool); - last; - } - } - } - $hastools = 1; - } - if (@{$available} > 0) { - if (@{$current{$user}{currtools}} > 0) { - if ("@{$available}" ne "@{$current{$user}{currtools}}") { - foreach my $tool (@{$available}) { - unless (grep/^$tool$/,@{$current{$user}{currtools}}) { - push(@{$current{$user}{newtools}},$tool); - } - } - } - } else { - @{$current{$user}{newtools}} = @{$available}; - } - if (@{$current{$user}{newtools}} > 0) { - $addtools = 1; - } - } - } - } - } - if (keys(%current) > 0) { - my %idhash; - foreach my $udom (keys(%allnames)) { - %{$idhash{$udom}} = &Apache::lonnet::idrget($udom, - keys(%{$allnames{$udom}})); - foreach my $uname (keys(%{$idhash{$udom}})) { - $current{$uname.':'.$udom}{'id'} = $idhash{$udom}{$uname}; - } - foreach my $uname (keys(%{$allnames{$udom}})) { - $current{$uname.':'.$udom}{'fullname'} = - &Apache::loncommon::plainname($uname,$udom, - 'lastname'); - } - } - $r->print(' + my ($current,$hastools,$addtools,$num_reenable,$num_activate,$num_expire) = + &Apache::longroup::group_memberlist($cdom,$cnum,$groupname,$fixedprivs, + $available); + if (keys(%{$current}) > 0) { + $r->print(' @@ -2188,8 +2294,8 @@ sub current_membership {
'.$lt{'desc'}.' '.$lt{'grfn'}.' '.$lt{'gran'}.''.$lt{'quot'}.' '.$lt{'dfac'}.'
$lt{'difn'} - $granularity + $granularity$quota Mb $lt{'stda'} $showstart
$lt{'enda'} $showend
'.&mt('Domain').' IDSection'.$lt{'func'}.'
   '.&mt('All:').' '); foreach my $tool (@{$available}) { $r->print('
'. $fullname.''.$uname.''. - $udom.''.$id.''.$id.''.$section.''. '       '); @@ -1695,7 +1880,7 @@ sub pick_new_members { sub privilege_specificity { my ($r,$tabcol,$rowColor1,$rowColor2,$action,$img,$tools,$stored, - $toolprivs,$fixedprivs,$available,$formname) = @_; + $toolprivs,$fixedprivs,$available,$formname,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash ( 'uprv' => 'User privileges', 'frty' => 'For each type of functionality you have chosen to include, '. @@ -1710,19 +1895,19 @@ sub privilege_specificity { 'privileges which apply to members with access to that '. 'functionality, and may also include additional privileges '. 'which can be set for specific members.', - 'cutg' => 'Currently the group is configured ', - 'sdif' => 'so different group members can receive different privileges.', - 'sall' => 'so all group members will receive the same privileges.', - 'algm' => 'All group members will receive the same privileges.', - 'smgp' => 'Some group members will receive different privileges from '. - 'others.', - 'thwi' => 'These will be the privileges all group members receive, '. - 'if you selected the first option above.', - 'thes' => 'These will be the privileges given to members assigned '. - 'in the future, including via automatic group assignment '. - 'for specific sections/roles ', - 'asyo' => 'As you have chosen not to include any functionality in the '. - 'group, no default user privileges settings need to be set.', + 'cutg' => "Currently the $gpterm is configured ", + 'sdif' => "so different $gpterm members can receive different privileges.", + 'sall' => "so all $gpterm members will receive the same privileges.", + 'algm' => "All $gpterm members will receive the same privileges.", + 'smgp' => "Some $gpterm members will receive different privileges from ". + "others.", + 'thwi' => "These will be the privileges all $gpterm members receive, ". + "if you selected the first option above.", + 'thes' => "These will be the privileges given to members assigned ". + "in the future, including via automatic $gpterm assignment ". + "for specific sections/roles ", + 'asyo' => "As you have chosen not to include any functionality in the ". + "$gpterm, no default user privileges settings need to be set.", 'plin' => 'Please indicate which optional privileges members '. 'will receive by default.', 'oppr' => 'Optional privileges', @@ -1987,11 +2172,11 @@ sub display_defprivs { sub change_members_form { my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$groupname,$description, $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata, - $granularity,$specificity,$idx,$states,$navbuttons,$rowColor1, - $rowColor2) = @_; + $granularity,$quota,$specificity,$idx,$states,$navbuttons,$rowColor1, + $rowColor2,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( - grse => 'Group settings', - mogm => 'Modify group membership', + grse => "$ucgpterm settings", + mogm => "Modify $gpterm membership", ); my @regexps = ('user_','userpriv_'); $r->print(&Apache::lonhtmlcommon::echo_form_input( @@ -2016,7 +2201,8 @@ sub change_members_form { '); &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2, $functions,$startdate,$enddate,$groupname, - $description,$granularity,\@available,\@unavailable); + $description,$granularity,$quota,\@available, + \@unavailable,$gpterm,$ucgpterm); $r->print('
 
  '); - if ($num_expire) { - &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'}); - } - if ($num_reenable) { - &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'}); - } - if ($num_activate) { - &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'}); + if ($num_expire) { + &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'}); + } + if ($num_reenable) { + &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'}); + } + if ($num_activate) { + &check_uncheck_buttons($r,$formname,'activate',$lt{'acti'}); + } + &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'}); + if (@{$available} > 0) { + if ($specificity eq 'Yes') { + &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'}); } - &check_uncheck_buttons($r,$formname,'deletion',$lt{'dele'}); - if (@{$available} > 0) { - if ($specificity eq 'Yes') { - &check_uncheck_buttons($r,$formname,'changepriv',$lt{'chpr'}); - } - if ($granularity eq 'Yes') { - $r->print(&check_uncheck_tools($r,$available)); - $r->print(' + if ($granularity eq 'Yes') { + $r->print(&check_uncheck_tools($r,$available)); + $r->print(' '); - } } - $r->print(<<"END"); + } + $r->print(<<"END");
'.$lt{'curf'}.' @@ -2173,9 +2279,9 @@ sub current_membership {
  END - $r->print(&Apache::lonhtmlcommon::start_pick_box()); - $r->print(<<"END"); + $r->print(&Apache::lonhtmlcommon::start_pick_box()); + $r->print(<<"END"); @@ -2201,135 +2307,134 @@ END END - my $colspan = 0; - if ($hastools) { - $r->print(''); - $colspan ++; - } - if ($addtools) { - $r->print(''); - $colspan ++; - } - $r->print(''); - if ($colspan) { - if ($granularity eq 'Yes') { - $r->print(' + my $colspan = 0; + if ($hastools) { + $r->print(''); + $colspan ++; + } + if ($addtools) { + $r->print(''); + $colspan ++; + } + $r->print(''); + if ($colspan) { + if ($granularity eq 'Yes') { + $r->print(''); } + $r->print(''); } - my %Sortby = (); - foreach my $user (sort(keys(%current))) { - if ($env{'form.sortby'} eq 'fullname') { - push(@{$Sortby{$current{$user}{fullname}}},$user); - } elsif ($env{'form.sortby'} eq 'username') { - push(@{$Sortby{$current{$user}{uname}}},$user); - } elsif ($env{'form.sortby'} eq 'domain') { - push(@{$Sortby{$current{$user}{udom}}},$user); - } elsif ($env{'form.sortby'} eq 'id') { - push(@{$Sortby{$current{$user}{id}}},$user); + } + my %Sortby = (); + foreach my $user (sort(keys(%{$current}))) { + if ($env{'form.sortby'} eq 'fullname') { + push(@{$Sortby{$$current{$user}{fullname}}},$user); + } elsif ($env{'form.sortby'} eq 'username') { + push(@{$Sortby{$$current{$user}{uname}}},$user); + } elsif ($env{'form.sortby'} eq 'domain') { + push(@{$Sortby{$$current{$user}{udom}}},$user); + } elsif ($env{'form.sortby'} eq 'id') { + push(@{$Sortby{$$current{$user}{id}}},$user); + } else { + push(@{$Sortby{$$current{$user}{fullname}}},$user); + } + } + my $rowNum = 0; + my $rowColor; + foreach my $key (sort(keys(%Sortby))) { + foreach my $user (@{$Sortby{$key}}) { + if ($rowNum %2 == 1) { + $rowColor = $rowColor1; } else { - push(@{$Sortby{$current{$user}{fullname}}},$user); + $rowColor = $rowColor2; } - } - my $rowNum = 0; - my $rowColor; - foreach my $key (sort(keys(%Sortby))) { - foreach my $user (@{$Sortby{$key}}) { - if ($rowNum %2 == 1) { - $rowColor = $rowColor1; - } else { - $rowColor = $rowColor2; - } - my $id = $current{$user}{id}; - my $fullname = $current{$user}{fullname}; - my $udom = $current{$user}{udom}; - my $uname = $current{$user}{uname}; - my $start = $current{$user}{start}; - my $end = $current{$user}{end}; - $r->print(' - + '); - if ($hastools) { - $r->print(''); + } + $r->print('   '); } - if ($addtools) { - $r->print(''); + } + if ($addtools) { + $r->print(''); } - $r->print(''."\n"); - $rowNum ++; + $r->print(''); } + $r->print(''."\n"); + $rowNum ++; } - $r->print(&Apache::lonhtmlcommon::end_pick_box()); - $r->print(' + } + $r->print(&Apache::lonhtmlcommon::end_pick_box()); + $r->print(' '); - } } return; } @@ -2357,13 +2462,13 @@ sub change_privs_form { my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate, $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools, $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$rowColor1, - $rowColor2) = @_; + $rowColor2,$gpterm,$ucgpterm) = @_; my @regexps = ('userpriv_'); my $nexttext; my %lt = &Apache::lonlocal::texthash( 'tode' => 'To be deleted', 'toex' => 'To be expired', - 'nome' => 'No members to be deleted or expired from the group.', + 'nome' => "No members to be deleted or expired from the $gpterm.", ); $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby'],\@regexps)); @@ -2402,12 +2507,13 @@ sub change_privs_form { ''); } - &topic_bar($r,$tabcol,4,&mt('Group member privileges')); + &topic_bar($r,$tabcol,4,&mt('[_1] member privileges',$ucgpterm)); my $numchgs = &member_privileges_form($r,$tabcol,$action,$formname,$tools, $toolprivs,$fixedprivs,$userdata, $usertools,$idx,$memchg,$states, - $stored,$rowColor1,$rowColor2); + $stored,$rowColor1,$rowColor2, + $gpterm); $r->print(''); my $prevtext = $$navbuttons{'gtps'}; if ($numchgs || $exp_or_del) { @@ -2422,8 +2528,8 @@ sub change_privs_form { sub add_members_form { my ($r,$tabcol,$action,$formname,$page,$startdate,$enddate,$groupname, - $description,$granularity,$sectioncount,$tools,$functions,$stored, - $states,$navbuttons,$rowColor1,$rowColor2) = @_; + $description,$granularity,$quota,$sectioncount,$tools,$functions, + $stored,$states,$navbuttons,$rowColor1,$rowColor2,$gpterm,$ucgpterm)=@_; $r->print('
$lt{'actn'}$lt{'stda'} $lt{'enda'}'.$lt{'curf'}.'Additional Functionality
'.$lt{'curf'}.'Additional Functionality
  '.&mt('All:'). ' '); - foreach my $tool (@{$available}) { - $r->print('
'); - if ($current{$user}{changestate} eq 'reenable') { - $r->print('
'); + if ($$current{$user}{changestate} eq 'reenable') { + $r->print('
'); - } elsif ($current{$user}{changestate} eq 'expire') { - $r->print('
'); - } elsif ($current{$user}{changestate} eq 'activate') { - $r->print('
'); - } - $r->print(''); - if ($specificity eq 'Yes') { - $r->print('
'); - } - $r->print(' + } + $r->print('
'. $fullname.''.$uname.''. $udom.''.$id.''.$start. ''.$end.''. + if ($hastools) { + $r->print(''. '      '); - foreach my $tool (@{$current{$user}{currtools}}) { - if ($granularity eq 'Yes') { - $r->print(''); - if ($granularity eq 'Yes') { - foreach my $tool (@{$current{$user}{newtools}}) { - $r->print(''); + if ($granularity eq 'Yes') { + foreach my $tool (@{$$current{$user}{newtools}}) { + $r->print('   '); - } - } else { - foreach my $tool (@{$current{$user}{newtools}}) { - $r->print('print(''.$tool. '   '); - } } - $r->print('
 
 
@@ -2435,7 +2541,8 @@ sub add_members_form { &check_tools($functions,$tools,\@available,\@unavailable); &print_current_settings($r,$action,$tabcol,$rowColor1,$rowColor2, $functions,$startdate,$enddate,$groupname, - $description,$granularity,\@available,\@unavailable); + $description,$granularity,$quota,\@available, + \@unavailable,$gpterm,$ucgpterm); $r->print(' @@ -2443,7 +2550,8 @@ sub add_members_form { '); - &membership_options($r,$action,$formname,$tabcol,$sectioncount,1); + &membership_options($r,$action,$formname,$tabcol,$sectioncount,1,$gpterm, + $ucgpterm); my $nexttext = $$navbuttons{'gtns'}; my $prevtext = $$navbuttons{'gtpp'}; &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, @@ -2456,7 +2564,8 @@ sub add_members_form { sub choose_privs_form { my ($r,$cdom,$cnum,$tabcol,$action,$formname,$page,$startdate,$enddate, $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx, - $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2) = @_; + $states,$stored,$sectioncount,$navbuttons,$rowColor1,$rowColor2, + $gpterm,$ucgpterm,$crstype) = @_; my @regexps = ('userpriv_'); my $nexttext; @@ -2474,11 +2583,11 @@ sub choose_privs_form { } $r->print('
 
'); - &topic_bar($r,$tabcol,6,&mt('Group member privileges')); + &topic_bar($r,$tabcol,6,&mt('[_1] member privileges',$ucgpterm)); &member_privileges_form($r,$tabcol,$action,$formname,$tools,$toolprivs, $fixedprivs,$userdata,$usertools,$idx,undef, - $states,$stored,$rowColor1,$rowColor2); + $states,$stored,$rowColor1,$rowColor2,$gpterm); $r->print(''); if ($action eq 'create') { @@ -2487,7 +2596,7 @@ sub choose_privs_form { my $img2 = 8; &mapping_options($r,$action,$formname,$page,$tabcol,$sectioncount, $states,$stored,$navbuttons,$img1,$img2, - $rowColor1,$rowColor2); + $rowColor1,$rowColor2,$gpterm,$ucgpterm,$crstype); } } my $prevtext = $$navbuttons{'gtps'}; @@ -2557,7 +2666,8 @@ function uncheckAllTools(formname) { sub member_privileges_form { my ($r,$tabcol,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata, - $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2) = @_; + $usertools,$idx,$memchg,$states,$stored,$rowColor1,$rowColor2, + $gpterm) = @_; my %lt = &Apache::lonlocal::texthash( 'addp' => 'Additional privileges', 'fixp' => 'Fixed privileges', @@ -2566,15 +2676,15 @@ sub member_privileges_form { 'forf' => 'For the functionality you have chosen to include '. 'there are no optional privileges to set besides '. 'the standard privileges.', - 'algr' => 'All group members will receive the same privileges.', - 'asno' => 'As no group members are being added, '. - 'there are no specific user privileges to set.', - 'asng' => 'As no group tools will be made available to users, '. - 'there are no specific user privileges to set.', - 'nogm' => 'No group member privileges to display or set, '. - 'as you have not indicated that you will be activating,'. - ' re-enabling, changing privileges, or adding/removing '. - 'functionality for any current members ', + 'algr' => "All $gpterm members will receive the same privileges.", + 'asno' => "As no $gpterm members are being added, ". + "there are no specific user privileges to set.", + 'asng' => "As no $gpterm tools will be made available to users, ". + "there are no specific user privileges to set.", + 'nogm' => "No $gpterm member privileges to display or set, ". + "as you have not indicated that you will be activating,". + " re-enabling, changing privileges, or adding/removing ". + "functionality for any current members ", 'full' => 'Fullname', 'user' => 'Username', 'doma' => 'Domain', @@ -2587,7 +2697,9 @@ sub member_privileges_form { } $specificity = $env{'form.specificity'}; } else { - @defprivs = @{$$stored{'defpriv'}}; + if (defined($$stored{'defpriv'})) { + @defprivs = @{$$stored{'defpriv'}}; + } $specificity = $$stored{'specificity'}; } my @showtools; @@ -2709,7 +2821,6 @@ END '
'); &display_defprivs($r,$tabcol,$rowColor1,$rowColor2,$tools, $toolprivs,\@defprivs); - } } else { if (keys(%{$usertools}) > 0) { @@ -2732,12 +2843,14 @@ sub process_request { my ($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) = @_; + $sectioncount,$stored,$rowColor1,$rowColor2,$gpterm,$ucgpterm, + $crstype) = @_; $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby'])); - my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum); + my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm, + $ucgpterm,$crstype); if ($earlyout) { $r->print('
 
@@ -2772,7 +2885,9 @@ sub process_request { @defprivs = @temp; } } else { - @defprivs = @{$$stored{'defpriv'}}; + if (defined($$stored{'defpriv'})) { + @defprivs = @{$$stored{'defpriv'}}; + } } my $outcome; @@ -2781,13 +2896,15 @@ sub process_request { $description,$startdate,$enddate, $specificity,$functions,$tools, $sectioncount,$roles,$types,$sections, - \@defprivs,$stored); + \@defprivs,$stored,$gpterm,$ucgpterm, + $crstype); } if (($action eq 'create' && $outcome eq 'ok') || (($action eq 'modify') && (($state eq 'memresult') || ($state eq 'addresult')))) { &process_membership($r,$cdom,$cnum,$action,$state,$groupname,$tools, $enddate,$startdate,$userdata,$idx,$toolprivs, - $usertools,$specificity,\@defprivs,$memchg); + $usertools,$specificity,\@defprivs,$memchg,$gpterm, + $ucgpterm); } return; } @@ -2795,7 +2912,7 @@ sub process_request { sub write_group_data { my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate, $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types, - $sections,$defprivs,$stored) = @_; + $sections,$defprivs,$stored,$gpterm,$ucgpterm,$crstype) = @_; my $now = time; my $creation = $now; my $creator = $env{'user.name'}.':'.$env{'user.domain'}; @@ -2803,12 +2920,28 @@ sub write_group_data { $creation = $$stored{'creation'}; $creator = $$stored{'creator'}; } - my $esc_description = &Apache::lonnet::escape($description); + my $esc_description = &escape($description); my @single_attributes = ('description','functions','startdate','enddate', 'creation','modified','creator','granularity', - 'specificity','autoadd','autodrop'); + 'specificity','autoadd','autodrop','quota'); my @mult_attributes = ('roles','types','sectionpick','defpriv'); - + + my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action, + $stored); + my $quota = $env{'form.quota'}; + + $quota =~ s/^\s*([^\s]*)\s*$/$1/; + if ($quota eq '') { + $quota = 0; + } + if ($quota !~ /^\d*\.?\d*$/) { + $quota = 0; + $r->print(&mt('The value you entered for the quota for the file repository in this [_1] contained invalid characters, so it has been set to 0 Mb. You can change this by modifying the [_1] settings.
',$gpterm)); + } + if ($quota > $maxposs) { + $quota = $maxposs; + $r->print(&mt('The value you entered for the quota for the file repository in this [_1] exceeded the maximum possible value, so it has been set to [_2] Mb (the maximum possible value).
',$gpterm,$maxposs)); + } my %groupinfo = ( description => $esc_description, startdate => $startdate, @@ -2820,7 +2953,9 @@ sub write_group_data { specificity => $specificity, autoadd => $env{'form.autoadd'}, autodrop => $env{'form.autodrop'}, + quota => $quota, ); + foreach my $func (keys(%{$functions})) { my $status; if (grep(/^$func$/,@{$tools})) { @@ -2847,14 +2982,11 @@ sub write_group_data { } my $autosec; my @autorole = &Apache::loncommon::get_env_multiple('form.autorole'); - + foreach my $role (@autorole) { if (defined($env{'form.sec_'.$role})) { my @autosections=&Apache::loncommon::get_env_multiple('form.sec_'. $role); - if (grep/^_all$/,@autosections) { - @autosections = sort {$a cmp $b} keys(%{$sectioncount}); - } $autosec .= ''; foreach my $sec (@autosections) { $autosec .= '
'.$sec.'
'; @@ -2870,34 +3002,43 @@ sub write_group_data { if ($result eq 'ok') { if ($action eq 'create') { - my $put_result = &create_homepage($cdom,$cnum,$groupname, - \%groupinfo,$tools); - $r->print('Group '.$groupname.' was created.
'); + my $result = &add_group_folder($cdom,$cnum,$now,$groupname,$action, + $description,$tools,\%groupinfo, + $gpterm,$ucgpterm,$crstype); + if ($result ne 'ok') { + $r->print(&mt('A problem occurred when creating folders for the new [_1]. [_2].
',$gpterm,$result)); + } + $r->print(&mt('[_1] [_2] was created.
',$ucgpterm,$groupname)); } else { - $r->print('Group '.$groupname.' was updated.
'); + $r->print(&mt('[_1] [_2] was updated.
',$ucgpterm,$groupname)); } } else { my %actiontype = ( 'create' => 'creating', 'modify' => 'modifying', ); - &Apache::lonnet::logthis('Failed to store group '.$groupname. - 'in course: '.$cnum.' in domain: '.$cdom); - $r->print(&mt('An error occurred when [_1] the new group. '. - 'Please try again.',$actiontype{$action})); + &Apache::lonnet::logthis("Failed to store $gpterm $groupname ". + 'in '.lc($crstype).': '.$cnum. + ' in domain: '.$cdom); + $r->print(&mt('An error occurred when [_1] the [_2]. '. + 'Please try again.',$actiontype{$action},$gpterm)); } return $result; } sub process_membership { my ($r,$cdom,$cnum,$action,$state,$groupname,$tools,$enddate,$startdate, - $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg)=@_; + $userdata,$idx,$toolprivs,$usertools,$specificity,$defprivs,$memchg, + $gpterm,$ucgpterm)=@_; my %usersettings = (); my %added= (); my %failed = (); my $num_ok = 0; my $num_fail = 0; my %group_privs = (); + my %curr_privs = (); + my %curr_start = (); + my %curr_end = (); my %tooltype = (); foreach my $tool (@{$tools}) { @@ -2916,7 +3057,7 @@ sub process_membership { } } else { if (@{$defprivs} > 0) { - foreach my $priv (@{$defprivs}) { + if (grep/^\Q$priv\E$/,@{$defprivs}) { foreach my $user (sort(keys(%{$usertools}))) { if ($$usertools{$user}{$tool}) { $group_privs{$user} .= $priv.':'; @@ -2936,6 +3077,7 @@ sub process_membership { my @expire = (); my @deletion = (); my @reenable = (); + my @unchanged = (); if ($state eq 'memresult') { if (ref($$memchg{'activate'}) eq 'ARRAY') { @activate = @{$$memchg{'activate'}}; @@ -2949,21 +3091,25 @@ sub process_membership { if (ref($$memchg{'reenable'}) eq 'ARRAY') { @reenable = @{$$memchg{'reenable'}}; } + my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, + $groupname); + foreach my $key (sort(keys(%membership))) { + if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { + ($curr_end{$1},$curr_start{$1},$curr_privs{$1}) = + split(/:/,$membership{$key},3); + } + } if (@expire + @deletion > 0) { - my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, - $groupname); foreach my $user (@expire) { - my ($currend,$currstart,@userprivs) = - split(/:/,$membership{$groupname.':'.$user}); - $group_privs{$user} = join(':',@userprivs); - if ($currstart > $now) { - $currstart = $now; + my $savestart = $curr_start{$user}; + if ($savestart > $now) { + $savestart = $now; } - $usersettings{$groupname.':'.$user} = $now.':'.$currstart.':'. - $group_privs{$user}; + $usersettings{$groupname.':'.$user} = $now.':'.$savestart.':'. + $curr_privs{$user}; if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname, - $user,$now,$currstart, - $group_privs{$user}) eq 'ok') { + $user,$now,$savestart, + $curr_privs{$user}) eq 'ok') { push(@{$added{'expired'}},$user); $num_ok ++; } else { @@ -2987,19 +3133,35 @@ sub process_membership { } foreach my $user (sort(keys(%{$usertools}))) { + if ((grep(/^$user$/,@expire)) || (grep(/^$user$/,@deletion))) { + next; + } my $type; my $start = $startdate; my $end = $enddate; if ($state eq 'memresult') { + if ($curr_privs{$user} eq $group_privs{$user}) { + push(@unchanged,$user); + next; + } + if (exists($curr_start{$user})) { + $start = $curr_start{$user}; + } + if (exists($curr_end{$user})) { + $end = $curr_end{$user}; + } $type = 'modified'; if (@activate > 0) { if (grep/^$user$/,@activate) { $start = $now; + $end = $enddate; $type = 'activated'; } } if (@reenable > 0) { if (grep/^$user$/,@reenable) { + $start = $startdate; + $end = $enddate; $type = 'reenabled'; } } @@ -3023,7 +3185,7 @@ sub process_membership { if ($num_ok) { foreach my $type (sort(keys(%added))) { $r->print(&mt('The following users were successfully [_1]',$type)); - if (!($type eq 'deleted' || $type eq 'expired')) { + if (!($type eq 'deleted' || $type eq 'expired')) { $r->print(&mt(' with the following privileges')); } $r->print(':
'); @@ -3044,6 +3206,7 @@ sub process_membership { } $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.$privlist.'
'); } + $r->print('
'); } } if ($num_fail) { @@ -3053,32 +3216,42 @@ sub process_membership { $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'
'); } } + $r->print('
'); + } + if (@unchanged > 0) { + $r->print(&mt('No change occurred for the following users:
')); + foreach my $user (sort(@unchanged)) { + $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.'
'); + } + $r->print('
'); } if ($roster_result eq 'ok') { - $r->print('
Group membership list updated.'); + $r->print('
'.&mt('[_1] membership list updated.',$ucgpterm)); + $r->print('

'.&mt("For full access to all of [_1]'s privileges, users will need to log out and log back in.",$groupname).'

'); } else { - $r->print('
An error occurred while updating the group membership list -'.$roster_result.'
'); + $r->print('
'.&mt('An error occurred while updating the [_1] membership list -',$gpterm).$roster_result.'
'); } return; } sub mapping_options { my ($r,$action,$formname,$page,$tabcol,$sectioncount,$states,$stored, - $navbuttons,$img1,$img2,$rowColor1,$rowColor2) = @_; + $navbuttons,$img1,$img2,$rowColor1,$rowColor2,$gpterm,$ucgpterm, + $crstype) = @_; my %lt = &Apache::lonlocal::texthash( - 'auto' => 'Settings for automatic group enrollment', - 'gmma' => 'Group membership mapping to specific sections/roles', - 'endi' => 'Enable/disable automatic group enrollment for '. - 'users in specified roles and sections', - 'adds' => 'If automatic group enrollment is enabled, when a user is assigned a course-wide or section-specific role, he/she will automatically be added as a member of the group, with start and end access dates defined by the default dates set for the group, unless he/she is already a group member, with access dates that permit either current or future group access.', - 'drops' => "If automatic group disenrollment is enabled, when a user's role is expired, access to the group will be terminated unless the user continues to have other course-wide or section-specific active or future roles which receive automatic membership in the group.", - 'pirs' => 'Pick roles and sections for automatic group enrollment', + 'auto' => "Settings for automatic $gpterm enrollment", + 'gmma' => "$ucgpterm membership mapping to specific sections/roles", + 'endi' => "Enable/disable automatic $gpterm enrollment for ". + "users in specified roles and sections", + 'adds' => "If automatic $gpterm enrollment is enabled, when a user is assigned a ".lc($crstype)."-wide or section-specific role, he/she will automatically be added as a member of the $gpterm, with start and end access dates defined by the default dates set for the $gpterm, unless he/she is already a $gpterm member, with access dates that permit either current or future $gpterm access.", + 'drops' => "If automatic $gpterm disenrollment is enabled, when a user's role is expired, access to the $gpterm will be terminated unless the user continues to have other ".lc($crstype)."-wide or section-specific active or future roles which receive automatic membership in the $gpterm.", + 'pirs' => "Pick roles and sections for automatic $gpterm enrollment", 'curr' => 'Currently set to', 'on' => 'on', 'off' => 'off', - 'auad' => 'Automatically enable group membership when roles are added?', - 'auex' => 'Automatically expire group membership when roles are removed?', - 'mapr' => 'Mapping of roles and sections affected by automatic group enrollment/disenrollment follows scheme chosen below.', + 'auad' => "Automatically enable $gpterm membership when roles are added?", + 'auex' => "Automatically expire $gpterm membership when roles are removed?", + 'mapr' => "Mapping of roles and sections affected by automatic $gpterm enrollment/disenrollment follows scheme chosen below.", ); &automapping($r,$action,$tabcol,$stored,\%lt,$img1); $r->print(' @@ -3086,7 +3259,7 @@ sub mapping_options {
'); &mapping_settings($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,\%lt, - $stored,$img2); + $stored,$img2,$crstype); return; } @@ -3115,7 +3288,7 @@ sub automapping { '; + if ($role eq 'cc') { + $sections_sel = ''; + } else { + $sections_sel=''; + } } if ($rowNum %2 == 1) { $rowColor = $rowColor1; @@ -3209,7 +3390,7 @@ sub mapping_settings { } sub standard_roles { - my @roles = ('st','ep','ta','in','cc'); + my @roles = ('cc','in','ta','ep','st'); return @roles; } @@ -3225,10 +3406,10 @@ sub my_custom_roles { } sub modify_menu { - my ($r,$groupname,$page) = @_; + my ($r,$groupname,$page,$gpterm) = @_; my @menu = ( - { text => 'Modify default group settings', + { text => "Modify default $gpterm settings", help => 'Course_Modify_Group', state => 'change_settings', branch => 'settings', @@ -3239,7 +3420,7 @@ sub modify_menu { state => 'change_members', branch => 'members', }, - { text => 'Add member(s) to the group', + { text => "Add member(s) to the $gpterm", help => 'Course_Group_Add_Members', state => 'add_members', branch => 'adds', @@ -3352,21 +3533,175 @@ sub date_setting_table { return ($start_table, $end_table); } +sub add_group_folder { + my ($cdom,$cnum,$now,$groupname,$action,$description,$tools,$groupinfo, + $gpterm,$ucgpterm,$crstype) = @_; + if ($cdom eq '' || $cnum eq '') { + return &mt('Error: invalid course domain or number - group folder creation failed'); + } + my ($outcome,$allgrpsmap,$grpmap,$boardsmap,$grppage); + my $navmap = Apache::lonnavmaps::navmap->new(); + my $crspath = '/uploaded/'.$cdom.'/'.$cnum.'/'; + $allgrpsmap = $crspath.'default_0.sequence'; + my $topmap = $navmap->getResourceByUrl($allgrpsmap); + undef($navmap); + if ($action eq 'create') { + # check if default_0.sequence exists. + if (!$topmap) { + my $grpstitle = &mt('[_1] [_2]',$crstype,$ucgpterm); + my $topmap_url = '/'.$env{'course.'.$env{'request.course.id'}.'.url'}; + $topmap_url =~ s|/+|/|g; + if ($topmap_url =~ m|^/uploaded|) { + $outcome = &map_updater($cdom,$cnum,'default_0.sequence', + 'toplevelgroup',$grpstitle,$topmap_url); + if ($outcome ne 'ok') { + return $outcome; + } + } else { + $outcome = &mt('Non-standard course - group folder not added.'); + return $outcome; + } + } + my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description; + $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/grppg'; + my $grptitle = &mt('Group homepage').' - '.$description; + my ($seqid,$discussions,$disctitle); + my $outcome = &map_updater($cdom,$cnum,'default_'.$now.'.sequence', + 'grpseq',$grpfolder,$allgrpsmap,$grppage, + $grptitle); + if ($outcome ne 'ok') { + return $outcome; + } + my $pageout = &create_homepage($cdom,$cnum,$groupname,$groupinfo, + $tools,$gpterm,$ucgpterm,$now); + # Link to folder for bulletin boards + $grpmap = $crspath.'default_'.$now.'.sequence'; + if (grep/^discussion$/,@{$tools}) { + $seqid = $now + 1; + $disctitle = &mt('Discussion Boards'); + my $outcome = &map_updater($cdom,$cnum,'default_'.$seqid. + '.sequence','bbseq',$disctitle,$grpmap); + if ($outcome ne 'ok') { + return $outcome; + } + $boardsmap = $crspath.'default_'.$seqid.'.sequence'; + } + } else { + #modify group folder if status of discussions tools is changed + } + my ($furl,$ferr)= &Apache::lonuserstate::readmap($cdom.'/'.$cnum); + $navmap = Apache::lonnavmaps::navmap->new(); + # modify parameters + my $parm_result; + if ($action eq 'create') { + if ($allgrpsmap) { + $parm_result .= &parm_setter($navmap,$cdom,$allgrpsmap,$groupname); + } + if ($grpmap) { + $parm_result .= &parm_setter($navmap,$cdom,$grpmap,$groupname); + } + if ($grppage) { + $parm_result .= &parm_setter($navmap,$cdom,$grppage,$groupname); + } + if ($boardsmap) { + $parm_result .= &parm_setter($navmap,$cdom,$boardsmap,$groupname); + } + } + if ($parm_result) { + return $parm_result; + } else { + return 'ok'; + } +} + +sub map_updater { + my ($cdom,$cnum,$newfile,$itemname,$itemtitle,$parentmap,$startsrc, + $starttitle,$endsrc,$endtitle) = @_; + my $outcome; + $env{'form.'.$itemname} = &new_map($startsrc,$starttitle,$endsrc, + $endtitle); + my $newmapurl=&Apache::lonnet::finishuserfileupload($cnum,$cdom,$itemname, + $newfile); + if ($newmapurl !~ m|^/uploaded|) { + $outcome = &mt('Error uploading new folder.')." ($newfile): $newmapurl".'
'; + return $outcome; + } + my ($errtext,$fatal)=&Apache::lonratedt::mapread($parentmap); + if ($fatal) { + $outcome = &mt('Error reading contents of parent folder')." ($parentmap): $errtext".'
'; + return $outcome; + } else { + my $newidx=&Apache::lonratedt::getresidx($newmapurl); + $Apache::lonratedt::resources[$newidx] = $itemtitle.':'.$newmapurl. + ':false:normal:res'; + $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx; + my ($outtext,$errtext) = &Apache::lonratedt::storemap($parentmap,1); + if ($errtext) { + $outcome = &mt('Error storing updated parent folder')." ($parentmap): $errtext".'
'; + return $outcome; + } + } + return 'ok'; +} + +sub new_map { + my ($startsrc,$starttitle,$endsrc,$endtitle) = @_; + my $newmapstr = ' + + + + + +'; + return $newmapstr; +} + +sub parm_setter { + my ($navmap,$cdom,$url,$groupname) = @_; + my $allresults; + my %hide_settings = ( + 'course' => { + 'num' => 13, + 'set' => 'yes', + }, + 'group' => { + 'num' => 5, + 'set' => 'no', + 'extra' => $groupname, + }, + ); + my $res = $navmap->getResourceByUrl($url); + my $symb = $res->symb(); + foreach my $level (keys(%hide_settings)) { + my $parmresult = &Apache::lonparmset::storeparm_by_symb($symb, + '0_hiddenresource', + $hide_settings{$level}{'num'}, + $hide_settings{$level}{'set'}, + 'string_yesno',undef,$cdom, + undef,undef, + $hide_settings{$level}{'extra'}); + if ($parmresult) { + $allresults .= $level.': '.$parmresult; + } + } + return $allresults; +} + sub create_homepage { - my ($cdom,$cnum,$name,$groupinfo,$tools) = @_; + my ($cdom,$cnum,$name,$groupinfo,$tools,$gpterm,$ucgpterm,$now) = @_; my $functionality = join(',',@{$tools}); - my $content = &Apache::lonnet::unescape($$groupinfo{description}); + my $content = &unescape($$groupinfo{description}); $content=~s/\s+$//s; $content=~s/^\s+//s; $content=~s/\$//s; $content=&Apache::lonfeedback::clear_out_html($content,1); my %pageinfo = ( - 'aaa_title' => 'Group: '.$name, + 'aaa_title' => "$ucgpterm: $name", 'abb_links' => $functionality, 'bbb_content' => $content, 'ccc_webreferences' => '', - 'uploaded.lastmodified' => time, + 'uploaded.lastmodified' => $now, ); my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum); return $putresult; @@ -3408,26 +3743,24 @@ function toggleTools(field,caller) { } sub validate_groupname { - my ($groupname,$action,$cdom,$cnum) = @_; - my %sectioncount; - my $numsec=&Apache::loncommon::get_sections($cdom,$cnum,\%sectioncount); - my %curr_groups; - my $numgroups=&Apache::loncommon::coursegroups(\%curr_groups,$cdom,$cnum); - + my ($groupname,$action,$cdom,$cnum,$gpterm,$ucgpterm,$crstype) = @_; + my %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum); + my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum); + my %lt = &Apache::lonlocal::texthash ( - igna => 'Invalid group name', - tgne => 'The group name entered ', - grna => 'Group names and section names used in a course '. - 'must be unique.', - isno => 'is not a valid name.', - gnmo => 'Group names may only contain letters, numbers '. - 'or underscores.', - cnnb => 'can not be used as it is the name of ', - inth => ' in this course.', - thgr => '- does not correspond to the name of an existing'. - ' group ', + igna => "Invalid $gpterm name", + tgne => "The $gpterm name entered ", + grna => "$ucgpterm names and section names used in a ". + "$crstype must be unique.", + isno => "is not a valid name.", + gnmo => "$ucgpterm names may only contain letters, ". + "numbers or underscores.", + cnnb => "can not be used as it is the name of ", + inth => " in this $crstype", + thgr => "- does not correspond to the name of an ". + "existing $gpterm", ); - + my $exitmsg = ''.$lt{'igna'}.'

'.$lt{'tgne'}.' "'. $groupname.'" '; my $dupmsg = $lt{'grna'}; @@ -3436,24 +3769,20 @@ sub validate_groupname { $earlyout = $exitmsg.$lt{'isno'}.'
'.$lt{'gnmo'}; return $earlyout; } - if ($numsec) { - if (exists($sectioncount{$groupname})) { - $earlyout = $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}. - '
'.$lt{'grna'}; - return $earlyout; - } + if (exists($sectioncount{$groupname})) { + return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}. + '
'.$lt{'grna'}; } - if ($action eq 'create') { - if ($numgroups) { - if (exists($curr_groups{$groupname})) { - $earlyout = $exitmsg.$lt{'cnnb'}.&mt('an existing group'). - $lt{'inth'}.'
'.$lt{'grna'}; - return $earlyout; - } - } + if ($action eq 'create' + && exists($curr_groups{$groupname})) { + + return $exitmsg.$lt{'cnnb'}.&mt('an existing [_1]',$gpterm). + $lt{'inth'}.'
'.$lt{'grna'}; + } elsif ($action eq 'modify') { unless(exists($curr_groups{$groupname})) { - $earlyout = &mt('Group name:').' '.$groupname.$lt{'thgr'}.$lt{'inth'}; + $earlyout = &mt('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}. + $lt{'inth'}; return $earlyout; } }
 
  '.$$lt{'auad'}.':  - on  off'); + '); if ($action eq 'modify') { $r->print('    ('.$$lt{'curr'}.' '.$$lt{$add}.')'); } @@ -3127,7 +3300,7 @@ sub automapping {   '.$$lt{'auex'}.':  - on  off'); + '); if ($action eq 'modify') { $r->print('    ('.$$lt{'curr'}.' '.$$lt{$drop}.')'); } @@ -3146,12 +3319,13 @@ sub automapping { } sub mapping_settings { - my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image) = @_; + my ($r,$tabcol,$rowColor1,$rowColor2,$sectioncount,$lt,$stored,$image, + $crstype) = @_; my @sections = keys(%{$sectioncount}); if (@sections > 0) { @sections = sort {$a cmp $b} @sections; - unshift(@sections,'_nosec'); # Put 'no sections' next - unshift(@sections,'_all'); # Put 'all' at the front of the list + unshift(@sections,'none'); # Put 'no sections' next + unshift(@sections,'all'); # Put 'all' at the front of the list } &topic_bar($r,$tabcol,$image,$$lt{'pirs'}); $r->print(' @@ -3172,11 +3346,18 @@ sub mapping_settings { my $rowNum = 0; my $rowColor; foreach my $role (@roles) { - my $plrole=&Apache::lonnet::plaintext($role); + my $plrole=&Apache::lonnet::plaintext($role,$crstype); my $sections_sel; if (@sections > 0) { - $sections_sel=''.§ions_selection(\@sections,'sec_'.$role). - ''. + &mt('all sections').''. + §ions_selection(\@sections,'sec_'.$role). + '