# The LearningOnline Network with CAPA # # $Id: loncoursegroups.pm,v 1.53 2006/07/19 23:28:20 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::loncoursegroups; use strict; use Apache::lonnet; use Apache::loncommon; use Apache::lonhtmlcommon; use Apache::lonlocal; use Apache::lonnavmaps; use Apache::longroup; use Apache::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; } # Needs to be in a course if (! ($env{'request.course.fn'})) { # Not in a course $env{'user.error.msg'}= "/adm/coursegroups:mdg:0:0:Cannot edit or view course groups"; return HTTP_NOT_ACCEPTABLE; } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','refpage','state','groupname','branch']); my $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'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); my $manage_permission = &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 => $ucgpterm.' home page', ); my %idx = (); $idx{id} = &Apache::loncoursedata::CL_ID(); $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME(); $idx{udom} = &Apache::loncoursedata::CL_SDOM(); $idx{uname} = &Apache::loncoursedata::CL_SNAME(); $idx{section} = &Apache::loncoursedata::CL_SECTION(); my $action = $env{'form.action'}; my $state = $env{'form.state'}; if ((!defined($action)) || ($action eq 'view') || ($action eq 'modify')) { if (!defined($state)) { $state = 'view'; } } if ($action eq 'create' || $action eq 'modify' || $action eq 'view') { if ($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(&mt('You do not have [_1] administration '. 'privileges in this [_2]',$gpterm,lc($crstype))); } } else { &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,$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(); }\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=>"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,$functions,$idx,$view_permission, $manage_permission,$action,$state,$gpterm,$ucgpterm,$crstype) = @_; my %curr_groups = (); my %grp_info = (); my %actionlinks = ( modify => ' ''.$lt{'crng'}.''); } } $r->print('

'); $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(<<"END"); $lt{'act'} $lt{'gname'} $lt{'desc'} $lt{'crea'} $lt{'crtd'} $lt{'last'} $lt{'func'} $lt{'quot'} $lt{'memb'} $lt{'file'} $lt{'dibd'} $lt{'dius'} END $r->print(&Apache::loncommon::end_data_table_header_row()); my %Sortby = (); foreach my $group (sort(keys(%curr_groups))) { %{$grp_info{$group}} = &Apache::longroup::get_group_settings( $curr_groups{$group}); my $members_result = &group_members($cdom,$cnum,$group, \%grp_info); my $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); } elsif ($env{'form.sortby'} eq 'creator') { push(@{$Sortby{$grp_info{$group}{'creator'}}},$group); } elsif ($env{'form.sortby'} eq 'creation') { push(@{$Sortby{$grp_info{$group}{'creation'}}},$group); } elsif ($env{'form.sortby'} eq 'modified') { push(@{$Sortby{$grp_info{$group}{'modified'}}},$group); } elsif ($env{'form.sortby'} eq 'quota') { push(@{$Sortby{$grp_info{$group}{'quota'}}},$group); } elsif ($env{'form.sortby'} eq 'totalmembers') { push(@{$Sortby{$grp_info{$group}{'totalmembers'}}}, $group); } elsif ($env{'form.sortby'} eq 'totalfiles') { push(@{$Sortby{$grp_info{$group}{'totalfiles'}}},$group); } elsif ($env{'form.sortby'} eq 'boards') { push(@{$Sortby{$grp_info{$group}{'boards'}}},$group); } elsif ($env{'form.sortby'} eq 'diskuse') { push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group); } else { push(@{$Sortby{$group}},$group); } } foreach my $key (sort(keys(%Sortby))) { foreach my $group (@{$Sortby{$key}}) { my $description = &unescape($grp_info{$group}{'description'}); my $creator = $grp_info{$group}{'creator'}; my $creation = $grp_info{$group}{'creation'}; my $modified = $grp_info{$group}{'modified'}; my $quota = $grp_info{$group}{'quota'}; my $totalmembers = $grp_info{$group}{'totalmembers'}; my $totalfiles = $grp_info{$group}{'totalfiles'}; my $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 ($grp_info{$group}{functions}{$tool} eq 'on') { $functionality .= ' '.$tool; } } if (!$functionality) { $functionality = &mt('None available'); } my $link = $actionlinks{$action}; if ($action eq 'modify' || $action eq 'delete') { $link .= $group; } else { $link .= $group.'/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'}.''; } } $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense'). ''.$link.''. ''.$group.''. ''.$description.''. ''.$creator.''. ''. &Apache::lonnavmaps::timeToHumanString($creation).''. ''. &Apache::lonnavmaps::timeToHumanString($modified).''. ''.$functionality.''. ''.$quota.''. ''.$totalmembers.''. ''.&mt('Files: ').$totalfiles.'
'.&mt('Folders: ').$totaldirs.''. ''.$boards.''. ''.$diskuse.''. &Apache::loncommon::end_data_table_row()); } } $r->print(&Apache::loncommon::end_data_table()); $r->print(''); if ($action eq 'view') { if (!defined($state)) { $state = 'view'; } $r->print(''); } } else { $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) { $r->print('

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

'); } } } else { $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,$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); if (defined($env{'form.groupname'})) { $groupname = $env{'form.groupname'}; } if (($action eq 'create') && ($state eq '')) { $state = 'pick_name'; } if (($action eq 'create') || (($action eq 'modify') && ($state eq 'chgresult'))) { ($startdate,$enddate) = &get_dates_from_form(); if (defined($env{'form.description'})) { $description = $env{'form.description'}; } if (defined($env{'form.tool'})) { @tools=&Apache::loncommon::get_env_multiple('form.tool'); } if (defined($env{'form.granularity'})) { $granularity=$env{'form.granularity'}; } if (defined($env{'form.specificity'})) { $specificity=$env{'form.specificity'}; } if (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 '') { if (defined($env{'form.groupname'})) { $state = 'pick_task'; } } 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'; } } } if (($action eq 'create') && ($state eq 'pick_name')) { $elements{'create'}{'pick_name'}{'types'} = 'selectbox'; $elements{'create'}{'pick_name'}{'roles'} = 'selectbox'; } if ((($action eq 'create') && (($state eq 'pick_name') || ($state eq 'pick_privs'))) || (($action eq 'modify') && (($state eq 'change_settings') || ($state eq 'add_members')))) { %sectioncount = &Apache::loncommon::get_sections($cdom,$cnum); $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox'; $elements{'modify'}{'change_mapping'}{'sectionpick'} = 'selectbox'; $elements{'modify'}{'add_members'}{'sectionpick'} = 'selectbox'; } if (($action eq 'create') || ($action eq 'modify' && $state eq 'pick_members')) { if (defined($env{'form.types'})) { @types=&Apache::loncommon::get_env_multiple('form.types'); } if (defined($env{'form.roles'})) { @roles=&Apache::loncommon::get_env_multiple('form.roles'); } if (defined($env{'form.sectionpick'})) { @sections=&Apache::loncommon::get_env_multiple('form.sectionpick'); if (grep/^all$/,@sections) { @buildsections = sort {$a cmp $b} keys(%sectioncount); } else { @buildsections = @sections; } } } 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 ($granularity eq 'Yes') { $elements{$action}{'change_members'}{'user_'.$tool} = 'checkbox'; } } if ($specificity eq 'Yes') { $elements{$action}{'change_members'}{'changepriv'} = 'checkbox'; } } } if (($state eq 'pick_privs') || ($state eq 'change_privs') || (($specificity eq 'No') && ($state eq 'memresult' || $state eq 'result' || $state eq 'addresult'))) { foreach my $tool (@tools) { my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool); foreach my $user (@values) { if ($state eq 'pick_privs' || $state eq 'result' || $state eq 'addresult') { if (!grep(/^\Q$user\E$/,@members)) { next; } } unless(exists($usertools{$user}{$tool})) { $usertools{$user}{$tool} = 1; } } } } if (($action eq 'modify') && (($state eq 'change_privs') || ($state eq 'memresult'))) { foreach my $chg (@member_changes) { if (defined($env{'form.'.$chg})) { @{$memchg{$chg}} = &Apache::loncommon::get_env_multiple('form.'.$chg); } } if ($state eq 'change_privs') { my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, $groupname); my $now = time; foreach my $key (sort(keys(%membership))) { if ($key =~ /^\Q$groupname\E:([^:]+:[^:]+)$/) { my $user = $1; my $changefunc = 0; my ($end,$start,@userprivs) = split(/:/,$membership{$key}); unless ($start == -1) { if (($end > 0) && ($end < $now)) { unless (grep/^$user$/,$memchg{'reenable'}) { next; } } my @currtools = (); if (@userprivs > 0) { foreach my $tool (sort(keys(%{$fixedprivs}))) { foreach my $priv (keys(%{$$fixedprivs{$tool}})) { if (grep/^$priv$/,@userprivs) { push(@currtools,$tool); last; } } } } foreach my $tool (@currtools) { if (keys(%{$usertools{$user}}) > 0) { if (!$usertools{$user}{$tool}) { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; last; } } else { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; } } if ($changefunc) { next; } if (keys(%{$usertools{$user}}) > 0) { foreach my $tool (keys(%{$usertools{$user}})) { if (!grep/^$tool$/,@currtools) { push(@{$memchg{'changefunc'}},$user); $changefunc = 1; last; } } } } } } &check_changes(\@member_changes,\%memchg); my %temptools; foreach my $change (@member_changes) { if (($change eq 'deletion') || ($change eq 'expire')) { next; } foreach my $user (@{$memchg{$change}}) { unless (exists($usertools{$user})) { %{$usertools{$user}} = (); } %{$temptools{$user}} = %{$usertools{$user}}; } } %usertools = %temptools; } elsif ($state eq 'memresult') { foreach my $change (@member_changes) { if ($change eq 'expire' || $change eq 'deletion') { next; } if (ref($memchg{$change}) eq 'ARRAY') { my @users = @{$memchg{$change}}; foreach my $user (@users) { unless (exists($usertools{$user})) { %{$usertools{$user}} = (); } } } } } } if ((($state eq 'pick_privs') || ($state eq 'change_privs')) && ($specificity eq 'Yes')) { foreach my $user (sort(keys(%usertools))) { foreach my $tool (keys(%{$usertools{$user}})) { foreach my $priv (keys(%{$$toolprivs{$tool}})) { unless (exists($$fixedprivs{$tool}{$priv})) { $elements{$action}{$state}{'userpriv_'.$priv} = 'checkbox'; } } } } } 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("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',}); if ($action eq 'modify') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups?refpage=enrl&action=modify", text=>"Groups", faq=>9,bug=>'Instructor Interface',}); } } else { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", text=>"Groups", faq=>9,bug=>'Instructor Interface',}); } my %trail = (); %{$trail{'create'}} = &Apache::lonlocal::texthash ( pick_name => $ucgpterm.' Settings', pick_members => 'Select Members', pick_privs => 'Choose Privileges', result => 'Creation Complete', ); %{$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', ); 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')) && ($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 ("Groups Manager")); &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( {href=>"javascript:backPage(document.$state,'$states{$action}[0]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } else { &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } } } } elsif (($action eq 'view') && ($view_permission)) { &Apache::lonhtmlcommon::add_breadcrumb( {text=>"View $gpterm".'s'}); $r->print(&Apache::lonhtmlcommon::breadcrumbs ('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,$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) = @_; if ($action eq 'create') { if ($state eq 'pick_name') { &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,$action,$state,$page,$startdate, $enddate,$groupname,$description,$granularity, $quota,$sectioncount,$tools,$functions,$stored, $states,$navbuttons,$gpterm,$ucgpterm); } 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 '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); } } } sub header { my ($bodytitle,$jscript,$action,$state,$page,$loaditems) = @_; my $start_page= &Apache::loncommon::start_page($bodytitle, '', {'add_entries' => $loaditems,}); my $output = <<"END"; $start_page
END if ($action eq 'create' || $action eq 'modify') { $output .= <<"END"; END } return $output; } sub onload_action { my ($action,$state) = @_; my %loaditems; if ((defined($env{'form.origin'})) && ($action eq 'create') && ($state eq 'pick_name' || $state eq 'pick_members' || $state eq 'pick_privs')) { unless ($env{'form.origin'} eq '') { $loaditems{'onload'} = 'javascript:setFormElements(document.'.$state.')'; } } if (($action eq 'modify') && ($state eq 'change_settings' || $state eq 'change_members' || $state eq 'change_privs' || $state eq 'add_members')) { $loaditems{'onload'} = 'javascript:setFormElements(document.'.$state.')'; } return \%loaditems; } sub footer { my $end_page = &Apache::loncommon::end_page(); return(< $end_page ENDFOOT } sub build_members_list { my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_; my %access = (); foreach my $role (@{$roles}) { %{$$users{$role}} = (); } foreach my $type (@{$types}) { $access{$type} = $type; } &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles, $sections,$users,$userdata); return; } sub group_files { 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; } sub group_members { my ($cdom,$cnum,$group,$group_info) = @_; my %memberhash = &Apache::lonnet::get_group_membership($cdom,$cnum,$group); my $now = time; my ($tmp)=keys(%memberhash); if ($tmp=~/^error:/) { $$group_info{'totalmembers'} = 'Unknown - an error occurred'; return $tmp; } my $totalmembers = 0; my $active = 0; my $previous = 0; my $future = 0; foreach my $member (keys %memberhash) { $totalmembers ++; my ($end,$start) = split(/:/,$memberhash{$member}); unless ($start == -1) { if (($end!=0) && ($end<$now)) { $previous ++; } elsif (($start!=0) && ($start>$now)) { $future ++; } else { $active ++; } } } if ($totalmembers == 0) { $$group_info{$group}{'totalmembers'} = 'None'; } else { $$group_info{$group}{'totalmembers'} = ''.$active. ' - active
'.$previous. ' - previous
'.$future. ' - future'; } return 'ok'; } sub general_settings_form { my ($r,$cdom,$cnum,$action,$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,$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); $nexttext = $$navbuttons{'mose'}; } $prevtext = $$navbuttons{'gtpp'}; &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); return; } sub groupsettings_options { my ($r,$functions,$action,$formname,$stored,$image,$gpterm, $ucgpterm,$crstype) = @_; my %lt = &Apache::lonlocal::texthash( 'gdat' => "Group access start and end dates", 'gnde' => "Group name, title and available collaborative tools", 'desc' => 'Group Title', 'func' => 'Collaborative Tools', 'gnam' => 'Group Name', 'lett' => 'Letters, numbers and underscore only', 'doyo' => 'Different subsets of the chosen collaborative tools '. 'for different group members?', ); my ($crsquota,$freespace,$maxposs) = &get_quota_constraints($action,$stored); &topic_bar($r,$image,$lt{'gnde'}); $r->print(' END my $numitems = keys(%{$functions}); my $halfnum = int($numitems/2); my $remnum = $numitems%2; if ($remnum) { $halfnum ++; } my @allfunctions = sort(keys (%{$functions})); for (my $i=0; $i<$halfnum; $i++) { $r->print(''); } $r->print(''); for (my $j=$halfnum; $j<@allfunctions; $j++) { $r->print(''); } if ($remnum) { $r->print(''); } $r->print('
'.$lt{'gnam'}.': '); if ($action eq 'create') { $r->print(' ('. $lt{'lett'}.')'); } else { $r->print(''.$env{'form.groupname'}); } $r->print(<<"END");
$lt{'desc'}:
$lt{'func'}:   '. '
     
'.&mt('Granularity:').' '.$lt{'doyo'}.'  '); if ($action eq 'modify') { $r->print('  ('.&mt('Currently set to "[_1]"', $$stored{'granularity'}).')'); } $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 can be divided amongst all [_2]s in the '. '[_3], and [_4] Mb are currently unallocated.',$crsquota, $gpterm,lc($crstype),sprintf("%.2f",$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].', sprintf("%.2f",$maxposs),$gpterm,lc($crstype))); } $r->print('
'); 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,$sectioncount,$image,$gpterm,$ucgpterm) = @_; my $crstype = &Apache::loncommon::course_type(); my %lt = &Apache::lonlocal::texthash( 'pipa' => 'Build a list of users for selection of group members', 'gmem' => "Group membership selection list criteria:", 'picr' => 'Pick the criteria to use to build a list of '. lc($crstype).' 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, there is no need to pick any criteria.", 'asub' => "A subsequent step will also allow you to specify automatic adding/dropping of group members triggered by specified user role and section changes in the course.", 'acty' => 'Access types', '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'), ); #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}); &topic_bar($r,$image,$lt{'pipa'}); $r->print(' '.$lt{'gmem'}.'
'.$lt{'picr'}); if ($action eq 'create') { $r->print($lt{'meof'}.'
'.$lt{'ifno'}.'
'.$lt{'asub'}); } else { $r->print($lt{'admg'}); } $r->print('

'.$lt{'acty'}.' '.$lt{'coro'}.' '.$lt{'cose'}.'
'); $r->print(&Apache::lonhtmlcommon::status_select_row(\%status_types)); $r->print(''); $r->print(&Apache::lonhtmlcommon::role_select_row(\@roles)); if (@sections > 0) { @sections = sort {$a cmp $b} @sections; unshift(@sections,'none'); # Put 'no sections' next unshift(@sections,'all'); # Put 'all' at the front of the list } else { @sections = ('all','none'); } $r->print(''. §ions_selection(\@sections,'sectionpick').'
'); return; } sub sections_selection { my ($sections,$elementname) = @_; my $section_sel; my $numvisible = 4; if (@{$sections} < 4) { $numvisible = @{$sections}; } foreach my $sec (@{$sections}) { if ($sec eq 'all') { $section_sel .= ' '."\n"; } elsif ($sec eq 'none') { $section_sel .= ' '."\n"; } else { $section_sel .= ' \n"; } } my $output = ' '; return $output; } sub access_date_settings { my ($r,$action,$formname,$stored,$image,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( '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 if ($action eq 'modify') { $starttime = $$stored{'startdate'}; unless ($$stored{'enddate'} == 0) { $endtime = $$stored{'enddate'}; } } my ($table) = &date_setting_table($starttime,$endtime,$formname); &topic_bar($r,$image,$lt{'sten'}); $r->print(' '.$table.' '); return; } sub choose_members_form { my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description, $granularity,$quota,$startdate,$enddate,$tools,$fixedprivs,$toolprivs, $functions,$users,$userdata,$idx,$stored,$states,$navbuttons, $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,$gpterm, $ucgpterm,$crstype); if ($earlyout) { $r->print($earlyout); &display_navbuttons($r,$formname,$$states{$action}[$page-1], $$navbuttons{'gtps'}); return; } my ($specimg,$memimg); my @available = (); my @unavailable = (); &check_tools($functions,$tools,\@available,\@unavailable); if ($action eq 'create') { &print_current_settings($r,$action,$functions,$startdate,$enddate, $groupname,$description,$granularity,$quota, \@available,\@unavailable,$gpterm,$ucgpterm); $specimg = 4; $memimg = 5; } else { $specimg = 2; $memimg = 3; my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, $groupname); foreach my $key (sort(keys(%membership))) { if ($key =~ /^\Q$groupname\E:([^:]+):([^:]+)$/) { my ($end,$start,@userprivs) = split(/:/,$membership{$key}); unless ($start == -1) { my $uname = $1; my $udom = $2; my $user = $uname.':'.$udom; $origmembers{$user} = 1; } } } } &privilege_specificity($r,$action,$specimg,$tools,$stored,$toolprivs, $fixedprivs,\@available,$formname,$gpterm,$ucgpterm); my $newusers = &pick_new_members($r,$action,$formname,\@available,$idx, $stored,$memimg,$users,$userdata, $granularity,\%origmembers,$gpterm, $ucgpterm); if ($newusers || $action eq 'create') { &display_navbuttons($r,$formname,$$states{$action}[$page-1], $$navbuttons{'gtps'},$$states{$action}[$page+1], $$navbuttons{'gtns'}); } else { &display_navbuttons($r,$formname,$$states{$action}[$page-1], $$navbuttons{'gtps'}); } return; } sub display_navbuttons { my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_; $r->print('
'); if ($prev) { $r->print('    '); } if ($next) { $r->print(' '); } $r->print('
'); } sub check_tools { my ($functions,$tools,$available,$unavailable) = @_; foreach my $item (sort(keys(%{$functions}))) { if (grep/^$item$/,@{$tools}) { push(@{$available},$item); } else { push(@{$unavailable},$item); } } return; } sub print_current_settings { my ($r,$action,$functions,$startdate,$enddate,$groupname,$description, $granularity,$quota,$available,$unavailable,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( grna => 'Group Name', desc => 'Group Title', grfn => "Collaborative Tools", gran => 'Granularity', quot => 'File quota', dfac => 'Default access dates', ygrs => "Your group selections - ", tfwa => "The following settings will apply to the group:", difn => 'Different collaborative tools
for different members:', stda => 'Start date', enda => 'End date:', ); my $showstart = &Apache::lonlocal::locallocaltime($startdate); my $showend; if ($enddate == 0) { $showend = &mt('No end date set'); } else { $showend = &Apache::lonlocal::locallocaltime($enddate); } if ($action eq 'create') { $r->print('
'.$lt{'ygrs'}.'
'.$lt{'tfwa'}.'
'); } $r->print(&Apache::loncommon::start_data_table('LC_course_group_status'). &Apache::loncommon::start_data_table_header_row()); $r->print(' '.$lt{'grna'}.' '.$lt{'desc'}.' '.$lt{'grfn'}.' '.$lt{'gran'}.' '.$lt{'quot'}.' '.$lt{'dfac'}.' '); $r->print(&Apache::loncommon::end_data_table_header_row(). &Apache::loncommon::start_data_table_row('LC_data_table_dense')); $r->print(' '.$groupname.' '.$description.' '); if (@{$available} > 0) { $r->print(&mt('Available for assignment to members:'). ''); my $rowcell = int(@{$available}/2) + @{$available}%2; for (my $i=0; $i<@{$available}; $i++) { if (@{$available} > 3) { if ($i==$rowcell) { $r->print(''); } } $r->print(''); } if ((@{$available} > 3) && (@{$available}%2)) { $r->print(''); } $r->print('
'.$$functions{$$available[$i]}. '   

'); } if (@{$unavailable} > 0) { $r->print(&mt('Unavailable for assignment:'). ''); my $rowcell = int(@{$unavailable}/2) + @{$unavailable}%2; for (my $j=0; $j<@{$unavailable}; $j++) { if (@{$unavailable} > 3) { if ($j==$rowcell) { $r->print(''); } } $r->print(''); } if ((@{$unavailable} > 3) && (@{$unavailable}%2)) { $r->print(''); } $r->print('
'.$$functions{$$unavailable[$j]}. '   
'); } $r->print(<<"END"); $lt{'difn'} $granularity $quota Mb $lt{'stda'} $showstart
$lt{'enda'} $showend END $r->print(&Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table()); return; } sub pick_new_members { my ($r,$action,$formname,$available,$idx,$stored,$img,$users,$userdata, $granularity,$origmembers,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( 'gpme' => "Group membership", 'addm' => 'Add members', 'setf' => 'Assign collaborative tools', 'func' => 'Tools', 'nome' => 'No members to add at this time, as there are no users '. 'matching the specified type(s), role(s) and section(s).', 'nnew' => "There are no users to add as new members, as all users". " matching the specified type(s), role(s), and ". "section(s) are already affiliated with this group.", '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.', ); my %members; my $totalusers = 0; my $newusers = 0; foreach my $role (keys(%{$users})) { foreach my $user (keys(%{$$users{$role}})) { $totalusers ++; if (ref($origmembers) eq 'HASH') { if (exists($$origmembers{$user})) { next; } } unless (defined($members{$user})) { @{$members{$user}} = @{$$userdata{$user}}; $newusers ++; } } } if (keys(%members) > 0) { if (@{$available} > 0 && $granularity eq 'Yes') { $r->print(&check_uncheck_tools($r,$available)); } } &topic_bar($r,$img,$lt{'gpme'}); if (keys(%members) > 0) { $r->print(' '); &check_uncheck_buttons($r,$formname,'member',$lt{'addm'}); if (@{$available} > 0 && $granularity eq 'Yes') { $r->print(''); } $r->print('
'.$lt{'setf'}.'   
'); $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(' '.&mt('Add?').' '.&mt('Name').' '.&mt('Username').' '.&mt('Domain').' '.&mt('ID').' '.&mt('Section').' '); if (@{$available} > 0) { $r->print(''.$lt{'func'}.''); } $r->print(&Apache::loncommon::end_data_table_header_row()); if (@{$available} > 0) { if ($granularity eq 'Yes') { $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'   '.&mt('All:').' '); foreach my $tool (@{$available}) { $r->print('   '); } $r->print(''); } } my %Sortby = (); foreach my $user (sort(keys(%members))) { if ($env{'form.sortby'} eq 'fullname') { push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user); } elsif ($env{'form.sortby'} eq 'username') { push(@{$Sortby{$members{$user}[$$idx{uname}]}},$user); } elsif ($env{'form.sortby'} eq 'domain') { push(@{$Sortby{$members{$user}[$$idx{udom}]}},$user); } elsif ($env{'form.sortby'} eq 'id') { push(@{$Sortby{$members{$user}[$$idx{id}]}},$user); } elsif ($env{'form.sortby'} eq 'section') { push(@{$Sortby{$members{$user}[$$idx{section}]}},$user); } else { push(@{$Sortby{$members{$user}[$$idx{fullname}]}},$user); } } foreach my $key (sort(keys(%Sortby))) { foreach my $user (@{$Sortby{$key}}) { my $id = $members{$user}[$$idx{id}]; my $fullname = $members{$user}[$$idx{fullname}]; my $udom = $members{$user}[$$idx{udom}]; my $uname = $members{$user}[$$idx{uname}]; my $section = $members{$user}[$$idx{section}]; $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense'). ''. ''.$fullname.''. ''.$uname.''. ''.$udom.''. ''.$id.''. ''.$section.''); if (@{$available} > 0) { $r->print(''. '       '); foreach my $tool (@{$available}) { if ($granularity eq 'Yes') { $r->print(''.$tool.'   '); } else { $r->print(''.$tool.'   '); } } $r->print(''); } $r->print(&Apache::loncommon::end_data_table_row()."\n"); } } $r->print(&Apache::loncommon::end_data_table()); } else { if ($totalusers > 0) { $r->print($lt{'nnew'}.'

'.$lt{'yoma'}); } else { $r->print($lt{'nome'}); } } return $newusers; } sub privilege_specificity { my ($r,$action,$img,$tools,$stored,$toolprivs,$fixedprivs,$available, $formname,$gpterm,$ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash ( 'uprv' => 'User privileges for collaborative tools', 'frty' => 'For each collaborative tool you have chosen to include, '. 'there is a set of core privileges which all group members '. 'assigned use of the tool will receive.', 'thar' => 'For some tools there are also additional optional '. 'privileges which can be set.', 'plch' => 'Choose one of the following:', 'fort' => 'For the collaborative tools you have chosen to include '. 'only core privileges are available, '. 'so there are no optional privileges to assign.', 'eaty' => 'Each collaborative tool includes core '. 'privileges assigned to all members with access to the '. 'tool. Some tools may also feature additional privileges '. 'which can be set for specific members.', 'cutg' => 'Currently the group is configured ', 'sdif' => 'so different members can receive different optional privileges for a particular tool.', 'sall' => 'so all members will receive the same optional privileges for a particular tool.', 'algm' => 'All group members will receive the same privileges for any tool assigned to them, including the default set of optional privileges.', 'smgp' => 'Different group members may receive different privileges from '. 'others for the tools they have been assigned.', 'thwi' => 'These will be the privileges all group members receive for a particular assigned tool, '. 'if you selected the first option above.', 'thes' => "These will be the privileges given to members assigned ". "in the future via automatic group assignment ". "for users who receive specific sections/roles in the course ", 'asyo' => "As you have chosen not to include any collaborative tools ". "in the group, no default optional privileges need to be set.", 'plin' => 'Indicate which optional privileges members '. 'will receive by default for a specific tool.', 'oppr' => 'Optional privileges', 'defp' => 'The default privileges new members will receive are:', ); my $totaloptionalprivs = 0; foreach my $tool (@{$tools}) { foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { if (!exists($$fixedprivs{$tool}{$priv})) { $totaloptionalprivs ++; } } } &topic_bar($r,$img,$lt{'uprv'}); if ((($action eq 'create') && (@{$available} > 0)) || (($action eq 'modify') && ($formname eq 'change_settings'))) { my %specific = ( 'No' => 'checked="checked"', 'Yes' => '', ); if ($action eq 'create') { $r->print($lt{'frty'}.'
'); if ($totaloptionalprivs) { $r->print($lt{'thar'}.'

'.$lt{'plch'}); } else { $r->print($lt{'fort'}); } } else { $r->print($lt{'eaty'}.' '.$lt{cutg}); if ($$stored{'specificity'} eq 'Yes') { $r->print($lt{'sdif'}); $specific{'Yes'} = $specific{'No'}; $specific{'No'} = ''; } else { $r->print($lt{'sall'}); } } if ($totaloptionalprivs) { $r->print('



'); } else { $r->print(''); } if ($totaloptionalprivs) { $r->print($lt{'plin'}); if ($action eq 'create') { $r->print('
'.$lt{'thwi'}); } $r->print('
'.$lt{'thes'}); if ($action eq 'create') { $r->print('('.&mt('if enabled on the next page').').'); } else { $r->print('('.&mt('if enabled below').').'); } $r->print('

'); &check_uncheck_buttons($r,$formname,'defpriv',$lt{'oppr'}); $r->print('

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

'); } &default_privileges($r,$action,$tools,$toolprivs,$fixedprivs, $available); } else { if ($action eq 'create') { $r->print($lt{'asyo'}); } elsif ($action eq 'modify' && $formname eq 'pick_members') { my @defprivs; if (ref($$stored{'defpriv'}) eq 'ARRAY') { @defprivs = @{$$stored{'defpriv'}}; } $r->print($lt{'eaty'}.' '.$lt{cutg}); if ($$stored{'specificity'} eq 'Yes') { $r->print($lt{'sdif'}); } else { $r->print($lt{'sall'}); } $r->print(' '.$lt{'defp'}.'

'); &display_defprivs($r,$tools,$toolprivs,\@defprivs); } } return; } sub default_privileges { my ($r,$action,$tools,$toolprivs,$fixedprivs,$available) = @_; my %lt = &Apache::lonlocal::texthash( 'addp' => 'Additional privileges', 'fixp' => 'Fixed privileges', 'oppr' => 'Optional privileges', 'func' => 'Collaborative Tool', ); $r->print(&Apache::lonhtmlcommon::start_pick_box('LC_group_priv_box'). &Apache::lonhtmlcommon::row_title($lt{'func'},undef, 'LC_groups_functionality')); $r->print(join('',@{$tools})); $r->print(&Apache::lonhtmlcommon::row_closure(1)); my $fixed = ''; my $dynamic = ''; foreach my $tool (@{$tools}) { my $privcount = 0; if ($dynamic ne '') { $dynamic .= ''; } $dynamic .= ''; foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { if (exists($$fixedprivs{$tool}{$priv})) { if ($fixed ne '') { $fixed .= ''."\n"; } $dynamic .= ''."\n"; } } if ($privcount == 0) { $dynamic .= ''."\n"; } if ($privcount < 3) { $dynamic .= ''."\n"; } elsif ($privcount%2) { $dynamic = ''."\n"; } $dynamic .= '
'; } $fixed .= ''.$$toolprivs{$tool}{$priv}.' '; if ($action eq 'modify') { if (grep(/^$tool$/,@{$available})) { $fixed .= ''.&mt('(on)').' '; } else { $fixed .= ''.&mt('(off)').' '; } } $fixed .= ''; } else { $privcount++; if ($privcount == 3) { $dynamic .= '
None  
'; } $r->print(&Apache::lonhtmlcommon::row_title($lt{'fixp'},undef, 'LC_groups_fixed'). $fixed. &Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::row_title($lt{'oppr'},undef, 'LC_groups_optional'). $dynamic. &Apache::lonhtmlcommon::end_pick_box()); $r->print('
'); return; } sub display_defprivs { my ($r,$tools,$toolprivs,$defprivs) = @_; my $function = &Apache::loncommon::get_users_function(); my $tabcol = &Apache::loncommon::designparm($function.'.tabbg'); my $rowColor1 = "#dddddd"; my $rowColor2 = "#eeeeee"; my %lt = &Apache::lonlocal::texthash( 'priv' => 'Privileges', 'func' => 'Collaborative Tool', ); $r->print(&Apache::lonhtmlcommon::start_pick_box()); $r->print(''); my $numrows = 0; my %currprivs; foreach my $tool (@{$tools}) { @{$currprivs{$tool}} = (); foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { if (ref($defprivs) eq 'ARRAY') { if (grep(/^\Q$priv\E$/,@{$defprivs})) { push(@{$currprivs{$tool}},$priv); } } } my $rowcount = int(@{$currprivs{$tool}}/3); if (@{$currprivs{$tool}}%3 > 0) { $rowcount ++; } if ($rowcount > $numrows) { $numrows = $rowcount; } } my @rowCols = ($rowColor1,$rowColor2); foreach my $tool (@{$tools}) { $r->print(' '); my $rownum = 1; my $privcount = 0; $r->print(''); foreach my $priv (@{$currprivs{$tool}}) { $privcount ++; if ($privcount%4 == 0) { $rownum ++; my $bgcol = $rownum%2; $r->print(''."\n"); } $r->print(''."\n"); } if ($privcount%3 > 0) { my $emptycells = 3-($privcount%3); while($emptycells > 0) { $r->print(''."\n"); $emptycells --; } } while ($rownum < $numrows) { $rownum ++; my $bgcol = $rownum%2; $r->print(''); } $r->print('
'.$tool.'
'.$$toolprivs{$tool}{$priv}.' 
 
'."\n".''); } $r->print(''."\n"); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print('
'); return; } sub change_members_form { my ($r,$cdom,$cnum,$action,$formname,$page,$groupname,$description, $startdate,$enddate,$tools,$fixedprivs,$functions,$users,$userdata, $granularity,$quota,$specificity,$idx,$states,$navbuttons,$gpterm, $ucgpterm) = @_; my %lt = &Apache::lonlocal::texthash( grse => "$ucgpterm settings", mogm => "Modify $gpterm membership", ); my @regexps = ('user_','userpriv_'); $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','expire','deletion', 'reenable','activate','changepriv','sortby', 'togglefunc'],\@regexps)); my $rowimg = 1; my @available = (); my @unavailable = (); &check_tools($functions,$tools,\@available,\@unavailable); my $nexttext = $$navbuttons{'gtns'}; my $prevtext = $$navbuttons{'gtpp'}; $r->print('
'); &topic_bar($r,1,$lt{'grse'}); &print_current_settings($r,$action,$functions,$startdate,$enddate, $groupname,$description,$granularity,$quota, \@available,\@unavailable,$gpterm,$ucgpterm); &topic_bar($r,2,$lt{'mogm'}); my $numcurrent = ¤t_membership($r,$cdom,$cnum,$formname,$groupname, \@available,\@unavailable,$fixedprivs, $granularity,$specificity); if ($numcurrent > 0) { &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); } else { &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext); } return; } sub current_membership { my ($r,$cdom,$cnum,$formname,$groupname,$available,$unavailable, $fixedprivs,$granularity,$specificity) = @_; my %membership = &Apache::lonnet::get_group_membership($cdom,$cnum, $groupname); my %lt = &Apache::lonlocal::texthash( 'actn' => 'Action?', 'name' => 'Name', 'usnm' => 'Username', 'doma' => 'Domain', 'stda' => 'Start Date', 'enda' => 'End Date', 'expi' => 'Expire', 'reen' => 'Re-enable', 'acti' => 'Activate', 'dele' => 'Delete', 'curf' => 'Current Tool Set', 'chpr' => 'Change Privileges' ); my ($current,$num_items,$hastools,$addtools) = &Apache::longroup::group_memberlist($cdom,$cnum,$groupname,$fixedprivs, $available); my $numcurrent = scalar(keys(%{$current})); if ($numcurrent > 0) { $r->print(' '); if ($num_items->{'active'}) { &check_uncheck_buttons($r,$formname,'expire',$lt{'expi'}); } if ($num_items->{'previous'}) { &check_uncheck_buttons($r,$formname,'reenable',$lt{'reen'}); } if ($num_items->{'future'}) { &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'}); } if ($granularity eq 'Yes') { $r->print(&check_uncheck_tools($r,$available)); $r->print(' '); } } $r->print(<<"END");
'.$lt{'curf'}.'   

END $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(<<"END"); $lt{'actn'} $lt{'name'} $lt{'usnm'} $lt{'doma'} ID $lt{'stda'} $lt{'enda'} END my $colspan = 0; if ($hastools) { $r->print(''.$lt{'curf'}.''); $colspan++; } if ($addtools) { $r->print(''.&mt('Additional Tools').''); $colspan++; } $r->print(&Apache::loncommon::end_data_table_header_row()); if ($colspan) { if ($granularity eq 'Yes') { $r->print(&Apache::loncommon::start_data_table_row('LC_data_table_dense LC_data_table_highlight').'   '.&mt('All:'). ' '); foreach my $tool (@{$available}) { $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); } else { push(@{$Sortby{$$current{$user}{fullname}}},$user); } } foreach my $key (sort(keys(%Sortby))) { foreach my $user (@{$Sortby{$key}}) { 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(&Apache::loncommon::start_data_table_row('LC_data_table_dense').' '); 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(' '. ''.$fullname.''. ''.$uname.''. ''. $udom.''. ''.$id.''. ''.$start.''. ''.$end.''); if ($hastools) { $r->print(''. '      '); foreach my $tool (@{$$current{$user}{currtools}}) { if ($granularity eq 'Yes') { $r->print(''); } else { $r->print(''.$tool); } $r->print('   '); } $r->print(''); } if ($addtools) { $r->print(''); if ($granularity eq 'Yes') { foreach my $tool (@{$$current{$user}{newtools}}) { $r->print('   '); } } else { foreach my $tool (@{$$current{$user}{newtools}}) { $r->print(''.$tool. '   '); } } $r->print(''); } $r->print(&Apache::loncommon::end_data_table_row()."\n"); } } $r->print(&Apache::loncommon::end_data_table()); } else { $r->print(&mt('There are no active, future or previous group members to modify.')); } return $numcurrent; } sub check_uncheck_buttons { my ($r,$formname,$field,$title,$colspan) = @_; $r->print('
'.$title.'   
'); } sub change_privs_form { my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate, $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools, $memchg,$idx,$states,$stored,$sectioncount,$navbuttons,$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 $gpterm.", ); $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby'],\@regexps)); if ($env{'form.branch'} eq 'adds') { $nexttext = $$navbuttons{'adme'}; } else { $nexttext = $$navbuttons{'mose'}; } &topic_bar($r,3,&mt('Members to delete or expire')); my $exp_or_del = 0; if (ref($$memchg{'deletion'}) eq 'ARRAY') { if (@{$$memchg{'deletion'}} > 0) { $r->print(''.$lt{'tode'}.':
    '); foreach my $user (@{$$memchg{'deletion'}}) { $r->print('
  • '.$$userdata{$user}[$$idx{fullname}]. ' ('.$user.')
  • '); } $r->print('
'); $exp_or_del += @{$$memchg{'deletion'}}; } } if (ref($$memchg{'expire'}) eq 'ARRAY') { if (@{$$memchg{'expire'}} > 0) { $r->print(''.$lt{'toex'}.':
    '); foreach my $user (@{$$memchg{'expire'}}) { $r->print('
  • '.$$userdata{$user}[$$idx{fullname}]. ' ('.$user.')
  • '); } $r->print('
'); $exp_or_del += @{$$memchg{'expire'}}; } } if (!$exp_or_del) { $r->print($lt{'nome'}.'
'); } &topic_bar($r,4,&mt('Setting optional privileges for specific group members')); my $numchgs = &member_privileges_form($r,$action,$formname,$tools, $toolprivs,$fixedprivs,$userdata, $usertools,$idx,$memchg,$states, $stored,$gpterm); my $prevtext = $$navbuttons{'gtps'}; if ($numchgs || $exp_or_del) { &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); } else { &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext); } return; } sub add_members_form { my ($r,$action,$formname,$page,$startdate,$enddate,$groupname, $description,$granularity,$quota,$sectioncount,$tools,$functions, $stored,$states,$navbuttons,$gpterm,$ucgpterm)=@_; $r->print('
'); my @available = (); my @unavailable = (); &check_tools($functions,$tools,\@available,\@unavailable); &print_current_settings($r,$action,$functions,$startdate,$enddate, $groupname,$description,$granularity,$quota, \@available,\@unavailable,$gpterm,$ucgpterm); &membership_options($r,$action,$formname,$sectioncount,1,$gpterm,$ucgpterm); my $nexttext = $$navbuttons{'gtns'}; my $prevtext = $$navbuttons{'gtpp'}; &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); return; } sub choose_privs_form { my ($r,$cdom,$cnum,$action,$formname,$page,$startdate,$enddate, $tools,$functions,$toolprivs,$fixedprivs,$userdata,$usertools,$idx, $states,$stored,$sectioncount,$navbuttons,$gpterm,$ucgpterm, $crstype) = @_; my @regexps = ('userpriv_'); my $nexttext; if ($action eq 'create') { push(@regexps,'sec_'); $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby','autoadd','autodrop'], \@regexps)); $nexttext = $$navbuttons{'crgr'}; } else { $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby'],\@regexps)); $nexttext = $$navbuttons{'adme'}; } &topic_bar($r,6,&mt('Setting optional privileges for specific group members')); &member_privileges_form($r,$action,$formname,$tools,$toolprivs, $fixedprivs,$userdata,$usertools,$idx,undef, $states,$stored,$gpterm); if ($action eq 'create') { my $img1 = 7; my $img2 = 8; &mapping_options($r,$action,$formname,$page,$sectioncount, $states,$stored,$navbuttons,$img1,$img2, $gpterm,$ucgpterm,$crstype); } my $prevtext = $$navbuttons{'gtps'}; &display_navbuttons($r,$formname,$$states{$action}[$page-1],$prevtext, $$states{$action}[$page+1],$nexttext); return; } sub build_boxes { my ($r,$tools,$usertools,$fixedprivs,$toolprivs,$showtools, $showboxes,$prefix,$specificity,$excluded) = @_; my $totalboxes = 0; if (@{$tools} > 0) { if ($specificity eq 'Yes') { foreach my $tool (@{$tools}) { @{$$showboxes{$tool}} = (); foreach my $user (sort(keys(%{$usertools}))) { if (ref($excluded) eq 'ARRAY') { if (grep/^$user$/,@{$excluded}) { next; } } if ($$usertools{$user}{$tool}) { unless (grep/^$tool$/,@{$showtools}) { push(@{$showtools},$tool); } foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { unless (exists($$fixedprivs{$tool}{$priv})) { unless(grep(/^$priv$/,@{$$showboxes{$tool}})) { push(@{$$showboxes{$tool}},$priv); $totalboxes ++; } } } } } } if ($totalboxes > 0) { $r->print(' '); } } } return $totalboxes; } sub member_privileges_form { my ($r,$action,$formname,$tools,$toolprivs,$fixedprivs,$userdata, $usertools,$idx,$memchg,$states,$stored,$gpterm) = @_; my %lt = &Apache::lonlocal::texthash( 'addp' => 'Additional privileges', 'fixp' => 'Core privileges', 'oppr' => 'Optional privileges', 'func' => 'Tool', 'forf' => 'For the collaborative tools included for group '. 'members being added or modified, '. 'there are no optional privileges to set '. 'for specific members.', '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 '. 'tools for any current members.', 'full' => 'Fullname', 'user' => 'Username', 'doma' => 'Domain', ); my @defprivs; my $specificity; if ($action eq 'create') { if (defined($env{'form.defpriv'})) { @defprivs = &Apache::loncommon::get_env_multiple('form.defpriv'); } $specificity = $env{'form.specificity'}; } else { if (defined($$stored{'defpriv'})) { @defprivs = @{$$stored{'defpriv'}}; } $specificity = $$stored{'specificity'}; } my @showtools; my %showboxes = (); my $numtools = 1 + @{$tools}; my @excluded = (); my $numchgs = 0; if ($formname eq 'change_privs') { my @currmembers = (); if (ref($$memchg{'deletion'}) eq 'ARRAY') { push(@excluded,@{$$memchg{'deletion'}}); } if (ref($$memchg{'expire'}) eq 'ARRAY') { push(@excluded,@{$$memchg{'expire'}}); } if (@excluded > 0) { foreach my $user (sort(keys(%{$usertools}))) { if (grep/^$user$/,@excluded) { next; } push(@currmembers,$user); } } else { @currmembers = sort(keys(%{$usertools})); } $numchgs = @currmembers; if (!$numchgs) { $r->print($lt{'nogm'}); return $numchgs; } } my $totalboxes = &build_boxes($r,$tools,$usertools,$fixedprivs, $toolprivs,\@showtools,\%showboxes, 'userpriv_',$specificity,\@excluded); if (@{$tools} > 0) { if ($specificity eq 'Yes') { if ($totalboxes > 0) { my $numcells = 2; my $colspan = $numcells + 1; my %total; if (keys(%{$usertools}) > 1) { $r->print(' '); foreach my $tool (@{$tools}) { if (@{$showboxes{$tool}} > 0) { $r->print(''); } } $r->print('
'); $r->print(''. ''); my $privcount = 0; foreach my $priv (@{$showboxes{$tool}}) { $privcount ++; if (($privcount == @{$showboxes{$tool}}) && ($privcount > 1)) { if ($privcount%$numcells) { $r->print(''); if ($privcount < @{$showboxes{$tool}}) { if (@{$showboxes{$tool}} > 2) { if ($privcount%$numcells == 0) { $r->print(''); } } else { $r->print(''); } } } $r->print('
'. $tool.'
'); } else { $r->print(''); } } else { $r->print(''); } $r->print(qq|
$$toolprivs{$tool}{$priv}  

|); $r->print('
 
'); } $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(<<"END"); $lt{'full'} $lt{'user'} $lt{'doma'} $lt{'addp'} END $r->print(&Apache::loncommon::end_data_table_header_row()); &member_privs_entries($r,$usertools,$toolprivs,$fixedprivs, $userdata,$idx,\@showtools,\@defprivs, \@excluded); $r->print(&Apache::loncommon::end_data_table()); } else { $r->print($lt{'forf'}.'
'); &display_defprivs($r,$tools,$toolprivs,\@defprivs); } } else { if (keys(%{$usertools}) > 0) { $r->print($lt{'algr'}.'

'); &display_defprivs($r,$tools,$toolprivs,\@defprivs); } else { $r->print($lt{'asno'}.'
'); } } } else { $r->print($lt{'asng'}); } return $numchgs; } sub process_request { my ($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) = @_; $r->print(&Apache::lonhtmlcommon::echo_form_input( ['origin','action','state','page','sortby'])); my $earlyout = &validate_groupname($groupname,$action,$cdom,$cnum,$gpterm, $ucgpterm,$crstype); if ($earlyout) { $r->print(' '); &display_navbuttons($r,$state,$$states{$action}[$page-1], $$navbuttons{'gtps'}); $r->print('
  '.$earlyout.'
'); return; } my @defprivs = (); if ($action eq 'create' || $state eq 'chgresult') { if (defined($env{'form.defpriv'})) { @defprivs = &Apache::loncommon::get_env_multiple('form.defpriv'); } if ($state eq 'chgresult') { my @okprivs = (); foreach my $tool (@{$tools}) { foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { push(@okprivs,$priv); } } my @temp = (); foreach my $defpriv (@defprivs) { if (grep/^$defpriv$/,@okprivs) { push(@temp,$defpriv); } } @defprivs = @temp; } } else { if (defined($$stored{'defpriv'})) { @defprivs = @{$$stored{'defpriv'}}; } } my $outcome; if ($action eq 'create' || $state eq 'chgresult') { $outcome = &write_group_data($r,$cdom,$cnum,$action,$state,$groupname, $description,$startdate,$enddate, $specificity,$functions,$tools, $sectioncount,$roles,$types,$sections, \@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,$gpterm, $ucgpterm); } return; } sub write_group_data { my ($r,$cdom,$cnum,$action,$state,$groupname,$description,$startdate, $enddate,$specificity,$functions,$tools,$sectioncount,$roles,$types, $sections,$defprivs,$stored,$gpterm,$ucgpterm,$crstype) = @_; my $now = time; my $creation = $now; my $creator = $env{'user.name'}.':'.$env{'user.domain'}; if ($state eq 'chgresult') { $creation = $$stored{'creation'}; $creator = $$stored{'creator'}; } my $esc_description = &escape($description); my @single_attributes = ('description','functions','startdate','enddate', 'creation','modified','creator','granularity', '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,sprintf("%.2f",$maxposs))); } my %groupinfo = ( description => $esc_description, startdate => $startdate, enddate => $enddate, creation => $creation, modified => $now, creator => $creator, granularity => $env{'form.granularity'}, specificity => $specificity, autoadd => $env{'form.autoadd'}, autodrop => $env{'form.autodrop'}, quota => $quota, ); foreach my $func (keys(%{$functions})) { my $status; if (grep(/^$func$/,@{$tools})) { $status = 'on'; } else { $status = 'off'; } $groupinfo{'functions'} .= qq|$status|; } $groupinfo{'roles'} = $roles; $groupinfo{'types'} = $types; $groupinfo{'sectionpick'} = $sections; $groupinfo{'defpriv'} = $defprivs; my %groupsettings = (); foreach my $item (@single_attributes) { $groupsettings{$groupname} .= qq|<$item>$groupinfo{$item}|; } foreach my $item (@mult_attributes) { foreach my $entry (@{$groupinfo{$item}}) { $groupsettings{$groupname} .= qq|<$item>$entry|; } } 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); $autosec .= ''; foreach my $sec (@autosections) { $autosec .= '
'.$sec.'
'; } $autosec .= '
'; } } if ($autosec) { $groupsettings{$groupname} .= qq|$autosec|; } my $result = &Apache::lonnet::modify_coursegroup($cdom,$cnum, \%groupsettings); if ($result eq 'ok') { if ($action eq 'create') { 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(&mt('[_1] [_2] was updated.
',$ucgpterm,$groupname)); } } else { my %actiontype = ( 'create' => 'creating', 'modify' => 'modifying', ); &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, $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}) { foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { $tooltype{$priv} = $tool; if ($specificity eq 'Yes') { my @users = &Apache::loncommon::get_env_multiple('form.userpriv_'.$priv); foreach my $user (@users) { $group_privs{$user} .= $priv.':'; if ($state eq 'memresult') { unless (exists($$usertools{$user}{$tool})) { $$usertools{$user}{$tool} = 1; } } } } else { if (@{$defprivs} > 0) { if (grep/^\Q$priv\E$/,@{$defprivs}) { foreach my $user (sort(keys(%{$usertools}))) { if ($$usertools{$user}{$tool}) { $group_privs{$user} .= $priv.':'; } } } } } } } foreach my $user (keys(%group_privs)) { $group_privs{$user} =~ s/:$//; } my $now = time; my @activate = (); my @expire = (); my @deletion = (); my @reenable = (); my @unchanged = (); if ($state eq 'memresult') { if (ref($$memchg{'activate'}) eq 'ARRAY') { @activate = @{$$memchg{'activate'}}; } if (ref($$memchg{'expire'}) eq 'ARRAY') { @expire = @{$$memchg{'expire'}}; } if (ref($$memchg{'deletion'}) eq 'ARRAY') { @deletion = @{$$memchg{'deletion'}}; } 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) { foreach my $user (@expire) { my $savestart = $curr_start{$user}; if ($savestart > $now) { $savestart = $now; } $usersettings{$groupname.':'.$user} = $now.':'.$savestart.':'. $curr_privs{$user}; if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname, $user,$now,$savestart, $curr_privs{$user}) eq 'ok') { push(@{$added{'expired'}},$user); $num_ok ++; } else { push(@{$failed{'expired'}},$user); $num_fail ++; } } foreach my $user (@deletion) { $usersettings{$groupname.':'.$user} = $now.':-1:'; if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname, $user,$now,'-1','') eq 'ok') { push(@{$added{'deleted'}},$user); $num_ok ++; } else { push(@{$failed{'deleted'}},$user); $num_fail ++; } } } } 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 (@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'; } } if ($type eq '') { 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'; } } else { $type = 'added'; } $usersettings{$groupname.':'.$user} = $end.':'.$start.':'. $group_privs{$user}; if (&Apache::lonnet::modify_group_roles($cdom,$cnum,$groupname, $user,$end,$start, $group_privs{$user}) eq 'ok') { push(@{$added{$type}},$user); $num_ok ++; } else { push(@{$failed{$type}},$user); $num_fail ++; } } my $roster_result = &Apache::lonnet::modify_coursegroup_membership($cdom, $cnum,\%usersettings); 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')) { $r->print(&mt(' with the following privileges')); } $r->print(':
'); foreach my $user (@{$added{$type}}) { my $privlist = ''; if (!($type eq 'deleted' || $type eq 'expired')) { $privlist = ': '; my @privs = split(/:/,$group_privs{$user}); my $curr_tool = ''; foreach my $priv (@privs) { unless ($curr_tool eq $tooltype{$priv}) { $curr_tool = $tooltype{$priv}; $privlist .= ''.$curr_tool.': '; } $privlist .= $$toolprivs{$curr_tool}{$priv}.', '; } $privlist =~ s/, $//; } $r->print($$userdata{$user}[$$idx{fullname}].' - '.$user.$privlist.'
'); } $r->print('
'); } } if ($num_fail) { foreach my $type (sort(keys(%failed))) { $r->print(&mt('The following users could not be [_1], because an error occurred:
',$type)); foreach my $user (@{$failed{$type}}) { $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('
'.&mt('[_1] membership list updated.',$ucgpterm)); $r->print('

'.&mt("Any currently logged in course users affected by the changes you made to group membership or privileges for the [_1] group will need to log out and log back in for their LON-CAPA sessions to reflect these changes.",$groupname).'

'); } else { $r->print('
'.&mt('An error occurred while updating the [_1] membership list -',$gpterm).$roster_result.'
'); } return; } sub mapping_options { my ($r,$action,$formname,$page,$sectioncount,$states,$stored, $navbuttons,$img1,$img2,$gpterm,$ucgpterm,$crstype) = @_; my %lt = &Apache::lonlocal::texthash( '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 newly 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 $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,$stored,\%lt,$img1); &mapping_settings($r,$sectioncount,\%lt,$stored,$img2,$crstype); return; } sub automapping { my ($r,$action,$stored,$lt,$image) = @_; my $add = 'off'; my $drop = 'off'; if (exists($$stored{'autoadd'})) { $add = $$stored{'autoadd'}; } if (exists($$stored{'autodrop'})) { $drop = $$stored{'autodrop'}; } &topic_bar($r,$image,$$lt{'endi'}); $r->print(' '.$$lt{'gmma'}.':
'.$$lt{'adds'}.'
'.$$lt{'drops'}.'

'.$$lt{'auad'}.':  '); if ($action eq 'modify') { $r->print('    ('.$$lt{'curr'}.' '.$$lt{$add}.')'); } $r->print('
'.$$lt{'auex'}.':  '); if ($action eq 'modify') { $r->print('    ('.$$lt{'curr'}.' '.$$lt{$drop}.')'); } $r->print('

'.$$lt{'mapr'}); } sub mapping_settings { my ($r,$sectioncount,$lt,$stored,$image,$crstype) = @_; my @sections = keys(%{$sectioncount}); if (@sections > 0) { @sections = sort {$a cmp $b} @sections; unshift(@sections,'none'); # Put 'no sections' next unshift(@sections,'all'); # Put 'all' at the front of the list } else { @sections = ('all','none'); } &topic_bar($r,$image,$$lt{'pirs'}); my @roles = &standard_roles(); my %customroles = &my_custom_roles(); $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(' '.&mt('Active?').' '.&mt('Role').''); if (@sections > 0) { $r->print(''.&mt('Sections').''); } $r->print(&Apache::loncommon::end_data_table_header_row()."\n"); foreach my $role (@roles) { my $plrole=&Apache::lonnet::plaintext($role,$crstype); my $sections_sel; if (@sections > 0) { if ($role eq 'cc') { $sections_sel = ''. &mt('all sections').''; } else { $sections_sel=''. §ions_selection(\@sections,'sec_'.$role). ''; } } $r->print(&Apache::loncommon::start_data_table_row(). ''.$plrole. ''.$sections_sel. &Apache::loncommon::end_data_table_row()); } foreach my $role (sort(keys(%customroles))) { my $sections_sel; if (@sections > 0) { $sections_sel = ''.§ions_selection(\@sections,'sec_'.$role).''; } $r->print(&Apache::loncommon::start_data_table_row(). ''.&mt('Custom role: '). ''.$role.''.$sections_sel. &Apache::loncommon::end_data_table_row()); } $r->print(&Apache::loncommon::end_data_table()); return; } sub standard_roles { my @roles = ('cc','in','ta','ep','st'); return @roles; } sub my_custom_roles { my %returnhash=(); my %rolehash=&Apache::lonnet::dump('roles'); foreach (keys %rolehash) { if ($_=~/^rolesdef\_(\w+)$/) { $returnhash{$1}=$1; } } return %returnhash; } sub modify_menu { my ($r,$groupname,$page,$gpterm) = @_; my @menu = ( { text => "Modify default $gpterm settings", help => 'Course_Modify_Group', state => 'change_settings', branch => 'settings', }, { text => 'Modify access, tools and/or privileges for previous, '. 'future, or current members', help => 'Course_Modify_Group_Membership', state => 'change_members', branch => 'members', }, { text => "Add member(s) to the $gpterm", help => 'Course_Group_Add_Members', state => 'add_members', branch => 'adds', }, ); my $menu_html = ''; foreach my $menu_item (@menu) { $menu_html .= '

'; $menu_html.= &mt($menu_item->{'text'}).''; if (exists($menu_item->{'help'})) { $menu_html.= &Apache::loncommon::help_open_topic($menu_item->{'help'}); } $menu_html.='

'.$/; } $r->print($menu_html); return; } sub member_privs_entries { my ($r,$usertools,$toolprivs,$fixedprivs,$userdata,$idx,$showtools, $defprivs,$excluded) = @_; foreach my $user (sort(keys(%{$usertools}))) { if (defined($excluded)) { if (ref($excluded) eq 'ARRAY') { if (grep/^$user$/,@{$excluded}) { next; } } } my ($uname,$udom) = split(/:/,$user); $r->print(&Apache::loncommon::start_data_table_row().' '.$$userdata{$user}[$$idx{fullname}].' '.$uname.' '.$udom.'
'. &mt('Collaborative Tool').'
'.&mt('Fixed').'
'.&mt('Optional').'
'); foreach my $tool (@{$showtools}) { if (exists($$usertools{$user}{$tool})) { $r->print(''); my $privcount = 0; my $fixed = ''; my $dynamic = ''; foreach my $priv (sort(keys(%{$$toolprivs{$tool}}))) { if (exists($$fixedprivs{$tool}{$priv})) { $fixed .= ''.$$toolprivs{$tool}{$priv}.' '; } else { $privcount ++; if ($privcount == 3) { $dynamic .= ''; } $dynamic .=''; } } $r->print(''.$dynamic.'
'.$tool.'
'.$fixed.'
'); } else { $r->print('
'.$tool.'
 
 
'); } } $r->print(&Apache::loncommon::end_data_table_row()); } } sub get_dates_from_form { my $startdate; my $enddate; $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate'); $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate'); if ( exists ($env{'form.no_end_date'}) ) { $enddate = 0; } return ($startdate,$enddate); } sub date_setting_table { my ($starttime,$endtime,$formname) = @_; my $startform = &Apache::lonhtmlcommon::date_setter($formname, 'startdate',$starttime); my $endform = &Apache::lonhtmlcommon::date_setter($formname, 'enddate',$endtime); my $perpetual = ''; my $table = "\n". ''. ''. ''."\n". ''. ''. ''."\n". "
'.&mt('Start:').''.$startform.' 
'.&mt('End:').''.$endform.''.$perpetual.'
\n"; return $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.'group_allfolders.sequence'; my $topmap = $navmap->getResourceByUrl($allgrpsmap); undef($navmap); if ($action eq 'create') { # check if group_allfolders.sequence exists. if (!$topmap) { my $grpstitle = &mt('[_1] [_2]s',$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,'group_allfolders.sequence', 'toplevelgroup',$grpstitle,$topmap_url); if ($outcome ne 'ok') { return $outcome; } } else { $outcome = &mt('Non-standard course - folder for all groups not added.'); return $outcome; } } my $grpfolder = &mt('[_1] Folder -',$ucgpterm,).$description; $grppage='/adm/'.$cdom.'/'.$cnum.'/'.$groupname.'/smppg'; my $grptitle = &mt('Group homepage').' - '.$description; my ($seqid,$discussions,$disctitle); my $outcome = &map_updater($cdom,$cnum,'group_folder_'.$groupname.'.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.'group_folder_'.$groupname.'.sequence'; if (grep/^discussion$/,@{$tools}) { $seqid = $now + 1; $disctitle = &mt('Discussion Boards'); my $outcome = &map_updater($cdom,$cnum,'group_boards_'.$groupname. '.sequence','bbseq',$disctitle,$grpmap); if ($outcome ne 'ok') { return $outcome; } $boardsmap = $crspath.'group_boards_'.$groupname.'.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,$gpterm,$ucgpterm,$now) = @_; my $functionality = join(',',@{$tools}); 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' => "$ucgpterm: $name", 'abb_links' => $functionality, 'bbb_content' => $content, 'ccc_webreferences' => '', 'uploaded.lastmodified' => $now, ); my $putresult = &Apache::lonnet::put('grppage_'.$name,\%pageinfo,$cdom,$cnum); return $putresult; } sub check_uncheck_tools { my ($r,$available) = @_; if (ref($available) eq 'ARRAY') { $r->print(' '); } return; } sub validate_groupname { 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 $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'}; my $earlyout; if (($groupname eq '') || ($groupname =~ /\W/)) { $earlyout = $exitmsg.$lt{'isno'}.'
'.$lt{'gnmo'}; return $earlyout; } if (exists($sectioncount{$groupname})) { return $exitmsg.$lt{'cnnb'}.&mt('a section').$lt{'inth'}. '
'.$lt{'grna'}; } 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('[_1] name:',$ucgpterm).' '.$groupname.$lt{'thgr'}. $lt{'inth'}; return $earlyout; } } return; } sub topic_bar { my ($r,$imgnum,$title) = @_; $r->print('
'.&mt('Step [_1]',$imgnum).
	      '  '.$title.'
'); return; } sub check_changes { my ($member_changes,$memchg) = @_; my %exclusions; @{$exclusions{'changefunc'}} = ('expire'); @{$exclusions{'changepriv'}} = ('expire','changefunc'); foreach my $change (@{$member_changes}) { if ($change eq 'deletion') { next; } my @checks = ('deletion'); if (exists($exclusions{$change})) { push(@checks,@{$exclusions{$change}}); } my @temp = (); foreach my $item (@{$$memchg{$change}}) { my $match = 0; foreach my $check (@checks) { if (defined($$memchg{$check})) { if (ref(@{$$memchg{$check}}) eq 'ARRAY') { if (@{$$memchg{$check}} > 0) { if (grep/^$item$/,@{$$memchg{$check}}) { $match = 1; last; } } } } } if ($match) { next; } push(@temp,$item); } @{$$memchg{$change}} = @temp; } } 1;