# # 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::Constants qw(:common :http); 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']); my $function = &Apache::loncommon::get_users_function(); my $tabcol = &Apache::loncommon::designparm($function.'.tabbg'); my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $view_permission = &Apache::lonnet::allowed('vcg',$env{'request.course.id'}); my $manage_permission = &Apache::lonnet::allowed('mdg',$env{'request.course.id'}); &Apache::lonhtmlcommon::clear_breadcrumbs(); my %functions = ( email => 'E-mail', discussion => 'Discussion boards', chat => 'Chat', files => 'File repository', roster => 'Membership roster', homepage => 'Group home page', ); my %idx = (); $idx{id} = &Apache::loncoursedata::CL_ID(); $idx{fullname} = &Apache::loncoursedata::CL_FULLNAME(); $idx{udom} = &Apache::loncoursedata::CL_SDOM(); $idx{uname} = &Apache::loncoursedata::CL_SNAME(); my $action = $env{'form.action'}; 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); } else { $r->print('You do not have group administration '. 'privileges in this course'); } } else { &print_main_menu($r,$cdom,$cnum,$function,$tabcol,\%functions,\%idx, $view_permission,$manage_permission); } return OK; } sub print_main_menu { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, $manage_permission) = @_; $r->print(&header('Course Groups',&mt('LON-CAPA Course Groups'), undef,undef,undef,$function)); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", text=>"Course Groups",}); $r->print(&Apache::lonhtmlcommon::breadcrumbs (undef,'Course Groups')); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission); $r->print(&footer()); return; } sub display_groups { my ($r,$cdom,$cnum,$function,$tabcol,$functions,$idx,$view_permission, $manage_permission) = @_; my %curr_groups = (); my %grp_info = (); my $rowColor1 = "#dddddd"; my $rowColor2 = "#eeeeee"; $r->print('

'); if ($view_permission) { if (&Apache::lonnet::get_coursegroups($cdom,$cnum,\%curr_groups) > 0) { $r->print(&Apache::lonhtmlcommon::start_pick_box()); if (keys(%curr_groups) > 0) { $r->print(<<"END"); END my %Sortby = (); foreach my $group (sort(keys(%curr_groups))) { %{$grp_info{$group}} = &Apache::loncommon::get_group_settings( $curr_groups{$group}); my $members_result = &group_members($group,\%grp_info); my $files_result = &group_files($group,\%grp_info); if ($env{'form.sortby'} eq 'groupname') { push(@{$Sortby{$group}},$group); } elsif ($env{'form.sortby'} eq 'description') { push(@{$Sortby{$grp_info{$group}{'description'}}}, $group); } elsif ($env{'form.sortby'} eq 'creator') { push(@{$Sortby{$grp_info{$group}{'creator'}}},$group); } elsif ($env{'form.sortby'} eq 'creation') { push(@{$Sortby{$grp_info{$group}{'creation'}}},$group); } elsif ($env{'form.sortby'} eq 'modified') { push(@{$Sortby{$grp_info{$group}{'modified'}}},$group); } elsif ($env{'form.sortby'} eq 'quota') { push(@{$Sortby{$grp_info{$group}{'quota'}}},$group); } elsif ($env{'form.sortby'} eq 'totalmembers') { push(@{$Sortby{$grp_info{$group}{'totalmembers'}}}, $group); } elsif ($env{'form.sortby'} eq 'totalfiles') { push(@{$Sortby{$grp_info{$group}{'totalfiles'}}}, $group); } elsif ($env{'form.sortby'} eq 'boards') { push(@{$Sortby{$grp_info{$group}{'boards'}}},$group); } elsif ($env{'form.sortby'} eq 'diskuse') { push(@{$Sortby{$grp_info{$group}{'diskuse'}}},$group); } else { push(@{$Sortby{$group}},$group); } } my $rowNum = 0; my $rowColor; foreach my $key (sort(keys(%Sortby))) { foreach my $group (@{$Sortby{$key}}) { if ($rowNum %2 == 1) { $rowColor = $rowColor1; } else { $rowColor = $rowColor2; } my $description = &Apache::lonnet::unescape($grp_info{$group}{'description'}); my $creator = $grp_info{$group}{'creator'}; my $creation = $grp_info{$group}{'creation'}; my $modified = $grp_info{$group}{'modified'}; my $quota = $grp_info{$group}{'quota'}; my $totalmembers = $grp_info{$group}{'totalmembers'}; my $totalfiles = $grp_info{$group}{'totalfiles'}; my $boards = $grp_info{$group}{'boards'}; my $diskuse = $grp_info{$group}{'diskuse'}; my $functionality; foreach my $tool (sort keys(%{$functions})) { if (defined($grp_info{$group}{functions}{$tool})) { $functionality .= ' '.$tool; } } if (!$functionality) { $functionality = 'None available'; } $r->print(''); $rowNum ++; } } $r->print('
Action Group Name Description Creator Created Last Modified Functionality Quota (Mb) Members Files Discussion boards Disk use
View Modify'.$group.''.$description.''.$creator.''. &Apache::lonnavmaps::timeToHumanString($creation).''. &Apache::lonnavmaps::timeToHumanString($modified).''.$functionality.''.$quota.''.$totalmembers.''.$totalfiles.''.$boards.''.$diskuse.'
'); $r->print(&Apache::lonhtmlcommon::end_pick_box()); } } else { $r->print('No groups exist'); } } else { $r->print('You do not have sufficient privileges to allow you to display course groups'); } return; } sub group_administration { my ($r,$action,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission) = @_; my %sectioncount = (); my @tools = (); my @types = (); my @roles = (); my @sections = (); my %users = (); my %userdata = (); my @members = (); my %usertools = (); my $state = $env{'form.state'}; my ($groupname,$description,$startdate,$enddate); if ($action eq 'create') { if ($state eq '') { $state = 'pick_name'; } else { ($startdate,$enddate) = &get_dates_from_form(); if (defined($env{'form.groupname'})) { $groupname = $env{'form.groupname'}; } if (defined($env{'form.description'})) { $description = $env{'form.description'}; } if (defined($env{'form.tool'})) { @tools=&Apache::loncommon::get_env_multiple('form.tool'); } if (defined($env{'form.member'})) { @members = &Apache::loncommon::get_env_multiple('form.member'); foreach my $user (@members) { %{$usertools{$user}} = (); } } } } my %toolprivs = (); %{$toolprivs{'email'}} = ( sgm => 'Send group mail', sgb => 'Broadcast mail', ); %{$toolprivs{'discussion'}} = ( cgb => 'Create boards', pgd => 'Post', pag => 'Anon. posts', rgi => 'Get identities', vgb => 'View boards', ); %{$toolprivs{'chat'}} = ( pgc => 'Chat', ); %{$toolprivs{'files'}} = ( rgf => 'Retrieve', ugf => 'Upload', dgf => 'Delete', ); %{$toolprivs{'roster'}} = ( vgm => 'View', ); %{$toolprivs{'homepage'}} = ( vgh => 'View page', mgh => 'Modify page', ); my %fixedprivs = (); %{$fixedprivs{'email'}} = ('sgm' => 1); %{$fixedprivs{'discussion'}} = ('vgb' => 1); %{$fixedprivs{'chat'}} = ('pgc' => 1); %{$fixedprivs{'files'}} = ('rgf' => 1); %{$fixedprivs{'roster'}} = ('vgm' => 1); %{$fixedprivs{'homepage'}} = ('vgh' => 1); my %elements = (); %{$elements{'create'}} = (); %{$elements{'modify'}} = (); %{$elements{'create'}{'pick_name'}} = ( startdate_month => 'selectbox', startdate_hour => 'selectbox', enddate_month => 'selectbox', enddate_hour => 'selectbox', types => 'selectbox', roles => 'selectbox', startdate_day => 'text', startdate_year => 'text', startdate_minute => 'text', startdate_second => 'text', enddate_day => 'text', enddate_year => 'text', enddate_minute => 'text', enddate_second => 'text', groupname => 'text', description => 'text', tool => 'checkbox', granularity => 'radio', no_end_date => 'checkbox', ); %{$elements{'create'}{'pick_members'}} = ( member => 'checkbox', ); if (($action eq 'create') && ($state eq 'pick_name')) { my $numsections = &Apache::loncommon::get_sections($cdom,$cnum, \%sectioncount); if ($numsections > 0) { $elements{'create'}{'pick_name'}{'sectionpick'} = 'selectbox'; } } if (($action eq 'create') && (($state eq 'pick_members') || ($state eq 'pick_privs'))) { if (defined($env{'form.types'})) { @types=&Apache::loncommon::get_env_multiple('form.types'); } if (defined($env{'form.roles'})) { @roles=&Apache::loncommon::get_env_multiple('form.roles'); } if (defined($env{'form.sectionpick'})) { @sections=&Apache::loncommon::get_env_multiple('form.sectionpick'); if (grep/^_all$/,@sections) { @sections = sort {$a cmp $b} keys(%sectioncount); } } &build_members_list($cdom,$cnum,\@types,\@roles, \@sections,\%users,\%userdata); if ((keys(%users) > 0) && (@tools > 0)) { foreach my $tool (@tools) { if ($env{'form.granularity'} eq 'Yes') { $elements{'create'}{'pick_members'}{'user_'.$tool} = 'checkbox'; } } $elements{'create'}{'pick_members'}{'specificity'} = 'radio'; } } if (($action eq 'create') && (($state eq 'pick_privs') || (($state eq 'result') && ($env{'form.specificity'} eq 'No')))) { foreach my $tool (@tools) { my @values = &Apache::loncommon::get_env_multiple('form.user_'.$tool); foreach my $user (@values) { unless(exists($usertools{$user}{$tool})) { $usertools{$user}{$tool} = 1; } } } if (($state eq 'pick_privs') && ($env{'form.specificity'} eq 'Yes')) { foreach my $member (@members) { foreach my $tool (keys(%{$usertools{$member}})) { foreach my $priv (keys(%{$toolprivs{$tool}})) { unless (exists($fixedprivs{$tool}{$priv})) { $elements{'create'}{'pick_privs'}{'userpriv_'.$priv} = 'checkbox'; } } } } } } my $jscript; if ($env{'form.action'} eq 'create') { $jscript = &Apache::loncommon::check_uncheck_jscript(); } $jscript .= qq| function nextPage(formname,nextstate) { formname.state.value= nextstate; formname.submit(); } function backPage(formname,prevstate) { formname.state.value = prevstate; formname.submit(); } |; $jscript .= &Apache::lonhtmlcommon::set_form_elements( \%{$elements{$action}{$state}}); my $loaditems = &onload_action($action,$state); $r->print(&header('Course Groups Manager',&mt('LON-CAPA Groups Manager'), $jscript,$action,$state,$function,$loaditems)); if ($env{'form.refpage'} eq 'enrl') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/dropadd", text=>"Enrollment Manager", faq=>9,bug=>'Instructor Interface',}); } else { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"/adm/coursegroups", text=>"Course Groups", faq=>9,bug=>'Instructor Interface',}); } my %states = (); @{$states{'create'}} = ('pick_name','pick_members','pick_privs','result'); @{$states{'modify'}} = (); my %trail = (); %{$trail{'create'}} = ( pick_name => 'Group Settings', pick_members => 'Select Members', pick_privs => 'Choose Privileges', result => 'Creation Complete', ); %{$trail{'modify'}} = (); 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 (undef,'Course Groups Manager')); &display_control($r,$cdom,$cnum,$tabcol,$action,$state, \%sectioncount,$groupname,$description,$functions, \@tools,\%toolprivs,\%fixedprivs,$startdate,$enddate, \%users,\%userdata,$idx,\@members,\%usertools); last; } else { if ($state eq 'result' && $i > 0) { &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[0]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } else { &Apache::lonhtmlcommon::add_breadcrumb( {href=>"javascript:backPage(document.$state,'$states{$action}[$i]')", text=>"$trail{$action}{$states{$action}[$i]}"}); } } } } elsif (($action eq 'view') && ($view_permission)) { &Apache::lonhtmlcommon::add_breadcrumb( {text=>"View groups"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs (undef,'Course Groups Manager')); &display_groups($r,$cdom,$cnum,$function,$tabcol,$functions,$idx, $view_permission,$manage_permission); } $r->print(&footer()); return; } sub display_control { my ($r,$cdom,$cnum,$tabcol,$action,$state,$sectioncount,$groupname, $description,$functions,$tools,$toolprivs,$fixedprivs,$startdate, $enddate,$users,$userdata,$idx,$members,$usertools) = @_; if ($action eq 'create') { if ($state eq 'pick_name') { &first_creation_form($r,$cdom,$cnum,$tabcol,$state,$functions, $sectioncount); } elsif ($state eq 'pick_members') { &second_creation_form($r,$cdom,$cnum,$tabcol,$state,$groupname, $description,$startdate,$enddate,$tools, $functions,$users,$userdata,$idx); } elsif ($state eq 'pick_privs') { &third_creation_form($r,$cdom,$cnum,$tabcol,$state,$startdate, $enddate,$tools,$functions,$toolprivs,$fixedprivs, $userdata,$members,$usertools,$idx); } elsif ($state eq 'result') { &completed_creation($r,$cdom,$cnum,$tabcol,$state,$groupname, $description,$userdata,$startdate,$enddate,$tools, $functions,$toolprivs,$members,$usertools,$idx); } } } sub header { my ($bodytitle,$title,$jscript,$action,$state,$function,$loaditems) = @_; my $html=&Apache::lonxml::xmlbegin(); my $bodytag=&Apache::loncommon::bodytag($bodytitle,$function,$loaditems); my $output = <<"END"; $html $title $bodytag
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.')"'; } } return $loaditems; } sub footer { return(< ENDFOOT } sub build_members_list { my ($cdom,$cnum,$types,$roles,$sections,$users,$userdata) = @_; my %access = (); foreach my $role (@{$roles}) { %{$$users{$role}} = (); } foreach my $type (@{$types}) { $access{$type} = $type; } &Apache::loncommon::get_course_users($cdom,$cnum,\%access,$roles, $sections,$users,$userdata); return; } sub group_files { return; } sub group_members { return; } sub first_creation_form { my ($r,$cdom,$cnum,$tabcol,$formname,$functions,$sectioncount) = @_; my %lt = &Apache::lonlocal::texthash( 'gmem' => 'Group membership options', 'picr' => 'Pick the criteria to use to build a list of course users '. 'from which you will select members of the new group', 'gdat' => 'Group open and close dates', 'sten' => 'Set a start date/time and end date/time for the group', 'acty' => 'Access types', 'coro' => 'Course roles', 'cose' => 'Course sections', 'gfun' => 'Group functionality', ); my %status_types = ( active => &mt('Currently has access'), previous => &mt('Previously had access'), future => &mt('Will have future access'), ); my @roles = ('st','cc','in','ta','ep','cr'); my $starttime = time; my $endtime = time+(6*30*24*60*60); # 6 months from now, approx my ($start_table,$end_table) = &date_setting_table ($starttime,$endtime,$formname); my @sections = (); my $section_sel = ''; my $numvisible = 4; @sections = sort {$a cmp $b} keys(%{$sectioncount}); if (@sections > 0) { unshift(@sections,'_all'); # Put 'all' at the front of the list if (@sections < 4) { $numvisible = @sections; } foreach (@sections) { if ($_ eq '_all') { $section_sel .= '