group MDL-19798 Updated print_header and build_navigation to OUTPUT and PAGE equivalents
[moodle.git] / group / autogroup.php
1 <?php // $Id$
2 /**
3  * Create and allocate users go groups
4  *
5  * @author  Matt Clarkson mattc@catalyst.net.nz
6  * @version 0.0.1
7  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8  * @package groups
9  */
11 require_once('../config.php');
12 require_once('lib.php');
13 require_once('autogroup_form.php');
15 if (!defined('AUTOGROUP_MIN_RATIO')) {
16     define('AUTOGROUP_MIN_RATIO', 0.7); // means minimum member count is 70% in the smallest group
17 }
19 $courseid = required_param('courseid', PARAM_INT);
20 $PAGE->set_url('/group/autogroup.php', array('courseid' => $courseid));
22 if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
23     print_error('invalidcourseid');
24 }
26 // Make sure that the user has permissions to manage groups.
27 require_login($course);
29 $context       = get_context_instance(CONTEXT_COURSE, $courseid);
30 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
31 require_capability('moodle/course:managegroups', $context);
33 $returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id;
35 $strgroups           = get_string('groups');
36 $strparticipants     = get_string('participants');
37 $strautocreategroups = get_string('autocreategroups', 'group');
39 // Print the page and form
40 $preview = '';
41 $error = '';
43 /// Get applicable roles
44 $rolenames = array();
45 if ($roles = get_roles_used_in_context($context, true)) {
46     $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
47     $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $systemcontext);
49     foreach ($roles as $role) {
50         if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
51             continue;
52         }
53         if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
54             continue;
55         }
56         $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
57     }
58 }
60 /// Create the form
61 $editform = new autogroup_form(null, array('roles' => $rolenames));
62 $editform->set_data(array('courseid' => $courseid, 'seed' => time()));
64 /// Handle form submission
65 if ($editform->is_cancelled()) {
66     redirect($returnurl);
68 } elseif ($data = $editform->get_data()) {
70     /// Allocate members from the selected role to groups
71     switch ($data->allocateby) {
72         case 'no':
73         case 'random':
74         case 'lastname':
75             $orderby = 'lastname, firstname'; break;
76         case 'firstname':
77             $orderby = 'firstname, lastname'; break;
78         case 'idnumber':
79             $orderby = 'idnumber'; break;
80         default:
81             print_error('unknoworder');
82     }
83     $users = groups_get_potential_members($data->courseid, $data->roleid, $orderby);
84     $usercnt = count($users);
86     if ($data->allocateby == 'random') {
87         srand($data->seed);
88         shuffle($users);
89     }
91     $groups = array();
93     // Plan the allocation
94     if ($data->groupby == 'groups') {
95         $numgrps    = $data->number;
96         $userpergrp = floor($usercnt/$numgrps);
98     } else { // members
99         $numgrps    = ceil($usercnt/$data->number);
100         $userpergrp = $data->number;
102         if (!empty($data->nosmallgroups) and $usercnt % $data->number != 0) {
103             // If there would be one group with a small number of member reduce the number of groups
104             $missing = $userpergrp * $numgrps - $usercnt;
105             if ($missing > $userpergrp * (1-AUTOGROUP_MIN_RATIO)) {
106                 // spread the users from the last small group
107                 $numgrps--;
108                 $userpergrp = floor($usercnt/$numgrps);
109             }
110         }
111     }
113     // allocate the users - all groups equal count first
114     for ($i=0; $i<$numgrps; $i++) {
115         $groups[$i] = array();
116         $groups[$i]['name']    = groups_parse_name(trim($data->namingscheme), $i);
117         $groups[$i]['members'] = array();
118         if ($data->allocateby == 'no') {
119             continue; // do not allocate users
120         }
121         for ($j=0; $j<$userpergrp; $j++) {
122             if (empty($users)) {
123                 break 2;
124             }
125             $user = array_shift($users);
126             $groups[$i]['members'][$user->id] = $user;
127         }
128     }
129     // now distribute the rest
130     if ($data->allocateby != 'no') {
131         for ($i=0; $i<$numgrps; $i++) {
132             if (empty($users)) {
133                 break 1;
134             }
135             $user = array_shift($users);
136             $groups[$i]['members'][$user->id] = $user;
137         }
138     }
140     if (isset($data->preview)) {
141         $table = new html_table();
142         if ($data->allocateby == 'no') {
143             $table->head  = array(get_string('groupscount', 'group', $numgrps));
144             $table->size  = array('100%');
145             $table->align = array('left');
146             $table->width = '40%';
147         } else {
148             $table->head  = array(get_string('groupscount', 'group', $numgrps), get_string('groupmembers', 'group'), get_string('usercounttotal', 'group', $usercnt));
149             $table->size  = array('20%', '70%', '10%');
150             $table->align = array('left', 'left', 'center');
151             $table->width = '90%';
152         }
153         $table->data  = array();
155         foreach ($groups as $group) {
156             $line = array();
157             if (groups_get_group_by_name($courseid, $group['name'])) {
158                 $line[] = '<span class="notifyproblem">'.get_string('groupnameexists', 'group', $group['name']).'</span>';
159                 $error = get_string('groupnameexists', 'group', $group['name']);
160             } else {
161                 $line[] = $group['name'];
162             }
163             if ($data->allocateby != 'no') {
164                 $unames = array();
165                 foreach ($group['members'] as $user) {
166                     $unames[] = fullname($user, true);
167                 }
168                 $line[] = implode(', ', $unames);
169                 $line[] = count($group['members']);
170             }
171             $table->data[] = $line;
172         }
174         $preview .= $OUTPUT->table($table);
176     } else {
177         $grouping = null;
178         $createdgrouping = null;
179         $createdgroups = array();
180         $failed = false;
182         // prepare grouping
183         if (!empty($data->grouping)) {
184             $groupingname = trim($data->groupingname);
185             if ($data->grouping < 0) {
186                 $grouping = new object();
187                 $grouping->courseid = $COURSE->id;
188                 $grouping->name     = $groupingname;
189                 $grouping->id = groups_create_grouping($grouping);
190                 $createdgrouping = $grouping->id;
191             } else {
192                 $grouping = groups_get_grouping($data->grouping);
193             }
194         }
196         // Save the groups data
197         foreach ($groups as $key=>$group) {
198             if (groups_get_group_by_name($courseid, $group['name'])) {
199                 $error = get_string('groupnameexists', 'group', $group['name']);
200                 $failed = true;
201                 break;
202             }
203             $newgroup = new object();
204             $newgroup->courseid = $data->courseid;
205             $newgroup->name     = $group['name'];
206             $groupid = groups_create_group($newgroup);
207             $createdgroups[] = $groupid;
208             foreach($group['members'] as $user) {
209                 groups_add_member($groupid, $user->id);
210             }
211             if ($grouping) {
212                 groups_assign_grouping($grouping->id, $groupid);
213             }
214         }
216         if ($failed) {
217             foreach ($createdgroups as $groupid) {
218                 groups_delete_group($groupid);
219             }
220             if ($createdgrouping) {
221                 groups_delete_grouping($createdgrouping);
222             }
223         } else {
224             redirect($returnurl);
225         }
226     }
229 $PAGE->navbar->add($strparticipants, new moodle_url($CFG->wwwroot.'/user/index.php', array('id'=>$courseid)));
230 $PAGE->navbar->add($strgroups, new moodle_url($CFG->wwwroot.'/group/index.php', array('id'=>$courseid)));
231 $PAGE->navbar->add($strautocreategroups);
233 /// Print header
234 $PAGE->set_title($strgroups);
235 $PAGE->set_heading(': '.$strgroups);
236 echo $OUTPUT->header();
237 echo $OUTPUT->heading($strautocreategroups);
239 if ($error != '') {
240     echo $OUTPUT->notification($error);
243 /// Display the form
244 $editform->display();
246 if($preview !== '') {
247         echo $OUTPUT->heading(get_string('groupspreview', 'group'));
249     echo $preview;
252 echo $OUTPUT->footer();
253 ?>