Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Auxiliary manual user enrolment lib, the main purpose is to lower memory requirements...
19
 *
20
 * @package    enrol_manual
21
 * @copyright  2010 Petr Skoda {@link http://skodak.org}
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
require_once($CFG->dirroot . '/user/selector/lib.php');
28
require_once($CFG->dirroot . '/enrol/locallib.php');
29
 
30
 
31
/**
32
 * Enrol candidates.
33
 */
34
class enrol_manual_potential_participant extends user_selector_base {
35
    protected $enrolid;
36
 
37
    public function __construct($name, $options) {
38
        $this->enrolid  = $options['enrolid'];
39
        $options['includecustomfields'] = true;
40
        parent::__construct($name, $options);
41
    }
42
 
43
    /**
44
     * Candidate users
45
     * @param string $search
46
     * @return array
47
     */
48
    public function find_users($search) {
49
        global $DB;
50
 
51
        // By default wherecondition retrieves all users except the deleted, not confirmed and guest.
52
        list($wherecondition, $params) = $this->search_sql($search, 'u');
53
        $params = array_merge($params, $this->userfieldsparams);
54
 
55
        $params['enrolid'] = $this->enrolid;
56
 
57
        $fields      = 'SELECT u.id, ' . $this->userfieldsselects;
58
        $countfields = 'SELECT COUNT(1)';
59
 
60
        $sql = " FROM {user} u
61
            LEFT JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = :enrolid)
62
                      $this->userfieldsjoin
63
                WHERE $wherecondition
64
                      AND ue.id IS NULL";
65
 
66
        list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext, $this->userfieldsmappings);
67
        $order = ' ORDER BY ' . $sort;
68
 
69
        if (!$this->is_validating()) {
70
            $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params);
71
            if ($potentialmemberscount > $this->maxusersperpage) {
72
                return $this->too_many_results($search, $potentialmemberscount);
73
            }
74
        }
75
 
76
        $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams));
77
 
78
        if (empty($availableusers)) {
79
            return array();
80
        }
81
 
82
 
83
        if ($search) {
84
            $groupname = get_string('enrolcandidatesmatching', 'enrol', $search);
85
        } else {
86
            $groupname = get_string('enrolcandidates', 'enrol');
87
        }
88
 
89
        return array($groupname => $availableusers);
90
    }
91
 
92
    protected function get_options() {
93
        $options = parent::get_options();
94
        $options['enrolid'] = $this->enrolid;
95
        $options['file']    = 'enrol/manual/locallib.php';
96
        return $options;
97
    }
98
}
99
 
100
/**
101
 * Enrolled users.
102
 */
103
class enrol_manual_current_participant extends user_selector_base {
104
    protected $courseid;
105
    protected $enrolid;
106
 
107
    public function __construct($name, $options) {
108
        $this->enrolid  = $options['enrolid'];
109
        $options['includecustomfields'] = true;
110
        parent::__construct($name, $options);
111
    }
112
 
113
    /**
114
     * Candidate users
115
     * @param string $search
116
     * @return array
117
     */
118
    public function find_users($search) {
119
        global $DB;
120
 
121
        // By default wherecondition retrieves all users except the deleted, not confirmed and guest.
122
        list($wherecondition, $params) = $this->search_sql($search, 'u');
123
        $params = array_merge($params, $this->userfieldsparams);
124
 
125
        $params['enrolid'] = $this->enrolid;
126
 
127
        $fields      = 'SELECT u.id, ' . $this->userfieldsselects;
128
        $countfields = 'SELECT COUNT(1)';
129
 
130
        $sql = " FROM {user} u
131
                 JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = :enrolid)
132
                      $this->userfieldsjoin
133
                WHERE $wherecondition";
134
 
135
        list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext, $this->userfieldsmappings);
136
        $order = ' ORDER BY ' . $sort;
137
 
138
        if (!$this->is_validating()) {
139
            $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params);
140
            if ($potentialmemberscount > $this->maxusersperpage) {
141
                return $this->too_many_results($search, $potentialmemberscount);
142
            }
143
        }
144
 
145
        $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams));
146
 
147
        if (empty($availableusers)) {
148
            return array();
149
        }
150
 
151
 
152
        if ($search) {
153
            $groupname = get_string('enrolledusersmatching', 'enrol', $search);
154
        } else {
155
            $groupname = get_string('enrolledusers', 'enrol');
156
        }
157
 
158
        return array($groupname => $availableusers);
159
    }
160
 
161
    protected function get_options() {
162
        $options = parent::get_options();
163
        $options['enrolid'] = $this->enrolid;
164
        $options['file']    = 'enrol/manual/locallib.php';
165
        return $options;
166
    }
167
}
168
 
169
/**
170
 * A bulk operation for the manual enrolment plugin to edit selected users.
171
 *
172
 * @copyright 2011 Sam Hemelryk
173
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
174
 */
175
class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_operation {
176
 
177
    /**
178
     * Returns the title to display for this bulk operation.
179
     *
180
     * @return string
181
     */
182
    public function get_title() {
183
        return get_string('editselectedusers', 'enrol_manual');
184
    }
185
 
186
    /**
187
     * Returns the identifier for this bulk operation. This is the key used when the plugin
188
     * returns an array containing all of the bulk operations it supports.
189
     */
190
    public function get_identifier() {
191
        return 'editselectedusers';
192
    }
193
 
194
    /**
195
     * Processes the bulk operation request for the given userids with the provided properties.
196
     *
197
     * @param course_enrolment_manager $manager
198
     * @param array $userids
199
     * @param stdClass $properties The data returned by the form.
200
     */
201
    public function process(course_enrolment_manager $manager, array $users, stdClass $properties) {
202
        global $DB, $USER;
203
 
204
        if (!has_capability("enrol/manual:manage", $manager->get_context())) {
205
            return false;
206
        }
207
 
208
        // Get all of the user enrolment id's.
209
        $ueids = array();
210
        $instances = array();
211
        foreach ($users as $user) {
212
            foreach ($user->enrolments as $enrolment) {
213
                $ueids[] = $enrolment->id;
214
                if (!array_key_exists($enrolment->id, $instances)) {
215
                    $instances[$enrolment->id] = $enrolment;
216
                }
217
            }
218
        }
219
 
220
        // Check that each instance is manageable by the current user.
221
        foreach ($instances as $instance) {
222
            if (!$this->plugin->allow_manage($instance)) {
223
                return false;
224
            }
225
        }
226
 
227
        // Collect the known properties.
228
        $status = $properties->status;
229
        $timestart = $properties->timestart;
230
        $timeend = $properties->timeend;
231
 
232
        list($ueidsql, $params) = $DB->get_in_or_equal($ueids, SQL_PARAMS_NAMED);
233
 
234
        $updatesql = array();
235
        if ($status == ENROL_USER_ACTIVE || $status == ENROL_USER_SUSPENDED) {
236
            $updatesql[] = 'status = :status';
237
            $params['status'] = (int)$status;
238
        }
239
        if (!empty($timestart)) {
240
            $updatesql[] = 'timestart = :timestart';
241
            $params['timestart'] = (int)$timestart;
242
        }
243
        if (!empty($timeend)) {
244
            $updatesql[] = 'timeend = :timeend';
245
            $params['timeend'] = (int)$timeend;
246
        }
247
        if (empty($updatesql)) {
248
            return true;
249
        }
250
 
251
        // Update the modifierid.
252
        $updatesql[] = 'modifierid = :modifierid';
253
        $params['modifierid'] = (int)$USER->id;
254
 
255
        // Update the time modified.
256
        $updatesql[] = 'timemodified = :timemodified';
257
        $params['timemodified'] = time();
258
 
259
        // Build the SQL statement.
260
        $updatesql = join(', ', $updatesql);
261
        $sql = "UPDATE {user_enrolments}
262
                   SET $updatesql
263
                 WHERE id $ueidsql";
264
 
265
        if ($DB->execute($sql, $params)) {
266
            foreach ($users as $user) {
267
                foreach ($user->enrolments as $enrolment) {
268
                    $enrolment->courseid  = $enrolment->enrolmentinstance->courseid;
269
                    $enrolment->enrol     = 'manual';
270
                    // Trigger event.
271
                    $event = \core\event\user_enrolment_updated::create(
272
                            array(
273
                                'objectid' => $enrolment->id,
274
                                'courseid' => $enrolment->courseid,
275
                                'context' => context_course::instance($enrolment->courseid),
276
                                'relateduserid' => $user->id,
277
                                'other' => array('enrol' => 'manual')
278
                                )
279
                            );
280
                    $event->trigger();
281
                }
282
            }
283
            // Delete cached course contacts for this course because they may be affected.
284
            cache::make('core', 'coursecontacts')->delete($manager->get_context()->instanceid);
285
            return true;
286
        }
287
 
288
        return false;
289
    }
290
 
291
    /**
292
     * Returns a enrol_bulk_enrolment_operation extension form to be used
293
     * in collecting required information for this operation to be processed.
294
     *
295
     * @param string|moodle_url|null $defaultaction
296
     * @param mixed $defaultcustomdata
297
     * @return enrol_manual_editselectedusers_form
298
     */
299
    public function get_form($defaultaction = null, $defaultcustomdata = null) {
300
        global $CFG;
301
        require_once($CFG->dirroot.'/enrol/manual/bulkchangeforms.php');
302
        return new enrol_manual_editselectedusers_form($defaultaction, $defaultcustomdata);
303
    }
304
}
305
 
306
 
307
/**
308
 * A bulk operation for the manual enrolment plugin to delete selected users enrolments.
309
 *
310
 * @copyright 2011 Sam Hemelryk
311
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
312
 */
313
class enrol_manual_deleteselectedusers_operation extends enrol_bulk_enrolment_operation {
314
 
315
    /**
316
     * Returns the title to display for this bulk operation.
317
     *
318
     * @return string
319
     */
320
    public function get_identifier() {
321
        return 'deleteselectedusers';
322
    }
323
 
324
    /**
325
     * Returns the identifier for this bulk operation. This is the key used when the plugin
326
     * returns an array containing all of the bulk operations it supports.
327
     *
328
     * @return string
329
     */
330
    public function get_title() {
331
        return get_string('deleteselectedusers', 'enrol_manual');
332
    }
333
 
334
    /**
335
     * Returns a enrol_bulk_enrolment_operation extension form to be used
336
     * in collecting required information for this operation to be processed.
337
     *
338
     * @param string|moodle_url|null $defaultaction
339
     * @param mixed $defaultcustomdata
340
     * @return enrol_manual_editselectedusers_form
341
     */
342
    public function get_form($defaultaction = null, $defaultcustomdata = null) {
343
        global $CFG;
344
        require_once($CFG->dirroot.'/enrol/manual/bulkchangeforms.php');
345
        if (!array($defaultcustomdata)) {
346
            $defaultcustomdata = array();
347
        }
348
        $defaultcustomdata['title'] = $this->get_title();
349
        $defaultcustomdata['message'] = get_string('confirmbulkdeleteenrolment', 'enrol_manual');
350
        $defaultcustomdata['button'] = get_string('unenrolusers', 'enrol_manual');
351
        return new enrol_manual_deleteselectedusers_form($defaultaction, $defaultcustomdata);
352
    }
353
 
354
    /**
355
     * Processes the bulk operation request for the given userids with the provided properties.
356
     *
357
     * @global moodle_database $DB
358
     * @param course_enrolment_manager $manager
359
     * @param array $userids
360
     * @param stdClass $properties The data returned by the form.
361
     */
362
    public function process(course_enrolment_manager $manager, array $users, stdClass $properties) {
363
        if (!has_capability("enrol/manual:unenrol", $manager->get_context())) {
364
            return false;
365
        }
366
        $counter = 0;
367
        foreach ($users as $user) {
368
            foreach ($user->enrolments as $enrolment) {
369
                $plugin = $enrolment->enrolmentplugin;
370
                $instance = $enrolment->enrolmentinstance;
371
                if ($plugin->allow_unenrol_user($instance, $enrolment)) {
372
                    $plugin->unenrol_user($instance, $user->id);
373
                    $counter++;
374
                }
375
            }
376
        }
377
        // Display a notification message after the bulk user unenrollment.
378
        if ($counter > 0) {
379
            \core\notification::info(get_string('totalunenrolledusers', 'enrol', $counter));
380
        }
381
        return true;
382
    }
383
}
384
 
385
/**
386
 * Migrates all enrolments of the given plugin to enrol_manual plugin,
387
 * this is used for example during plugin uninstallation.
388
 *
389
 * NOTE: this function does not trigger role and enrolment related events.
390
 *
391
 * @param string $enrol  The enrolment method.
392
 */
393
function enrol_manual_migrate_plugin_enrolments($enrol) {
394
    global $DB;
395
 
396
    if ($enrol === 'manual') {
397
        // We can not migrate to self.
398
        return;
399
    }
400
 
401
    $manualplugin = enrol_get_plugin('manual');
402
 
403
    $params = array('enrol'=>$enrol);
404
    $sql = "SELECT e.id, e.courseid, e.status, MIN(me.id) AS mid, COUNT(ue.id) AS cu
405
              FROM {enrol} e
406
              JOIN {user_enrolments} ue ON (ue.enrolid = e.id)
407
              JOIN {course} c ON (c.id = e.courseid)
408
         LEFT JOIN {enrol} me ON (me.courseid = e.courseid AND me.enrol='manual')
409
             WHERE e.enrol = :enrol
410
          GROUP BY e.id, e.courseid, e.status
411
          ORDER BY e.id";
412
    $rs = $DB->get_recordset_sql($sql, $params);
413
 
414
    foreach($rs as $e) {
415
        $minstance = false;
416
        if (!$e->mid) {
417
            // Manual instance does not exist yet, add a new one.
418
            $course = $DB->get_record('course', array('id'=>$e->courseid), '*', MUST_EXIST);
419
            if ($minstance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'))) {
420
                // Already created by previous iteration.
421
                $e->mid = $minstance->id;
422
            } else if ($e->mid = $manualplugin->add_default_instance($course)) {
423
                $minstance = $DB->get_record('enrol', array('id'=>$e->mid));
424
                if ($e->status != ENROL_INSTANCE_ENABLED) {
425
                    $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$e->mid));
426
                    $minstance->status = ENROL_INSTANCE_DISABLED;
427
                }
428
            }
429
        } else {
430
            $minstance = $DB->get_record('enrol', array('id'=>$e->mid));
431
        }
432
 
433
        if (!$minstance) {
434
            // This should never happen unless adding of default instance fails unexpectedly.
435
            debugging('Failed to find manual enrolment instance', DEBUG_DEVELOPER);
436
            continue;
437
        }
438
 
439
        // First delete potential role duplicates.
440
        $params = array('id'=>$e->id, 'component'=>'enrol_'.$enrol, 'empty'=>'');
441
        $sql = "SELECT ra.id
442
                  FROM {role_assignments} ra
443
                  JOIN {role_assignments} mra ON (mra.contextid = ra.contextid AND mra.userid = ra.userid AND mra.roleid = ra.roleid AND mra.component = :empty AND mra.itemid = 0)
444
                 WHERE ra.component = :component AND ra.itemid = :id";
445
        $ras = $DB->get_records_sql($sql, $params);
446
        $ras = array_keys($ras);
447
        $DB->delete_records_list('role_assignments', 'id', $ras);
448
        unset($ras);
449
 
450
        // Migrate roles.
451
        $sql = "UPDATE {role_assignments}
452
                   SET itemid = 0, component = :empty
453
                 WHERE itemid = :id AND component = :component";
454
        $params = array('empty'=>'', 'id'=>$e->id, 'component'=>'enrol_'.$enrol);
455
        $DB->execute($sql, $params);
456
 
457
        // Delete potential enrol duplicates.
458
        $params = array('id'=>$e->id, 'mid'=>$e->mid);
459
        $sql = "SELECT ue.id
460
                  FROM {user_enrolments} ue
461
                  JOIN {user_enrolments} mue ON (mue.userid = ue.userid AND mue.enrolid = :mid)
462
                 WHERE ue.enrolid = :id";
463
        $ues = $DB->get_records_sql($sql, $params);
464
        $ues = array_keys($ues);
465
        $DB->delete_records_list('user_enrolments', 'id', $ues);
466
        unset($ues);
467
 
468
        // Migrate to manual enrol instance.
469
        $params = array('id'=>$e->id, 'mid'=>$e->mid);
470
        if ($e->status != ENROL_INSTANCE_ENABLED and $minstance->status == ENROL_INSTANCE_ENABLED) {
471
            $status = ", status = :disabled";
472
            $params['disabled'] = ENROL_USER_SUSPENDED;
473
        } else {
474
            $status = "";
475
        }
476
        $sql = "UPDATE {user_enrolments}
477
                   SET enrolid = :mid $status
478
                 WHERE enrolid = :id";
479
        $DB->execute($sql, $params);
480
    }
481
    $rs->close();
482
}
483
 
484
/**
485
 * Gets an array of the cohorts that can be enrolled in this course.
486
 *
487
 * @param int $enrolid
488
 * @param string $search
489
 * @param int $page Defaults to 0
490
 * @param int $perpage Defaults to 25
491
 * @param int $addedenrollment
492
 * @return array Array(totalcohorts => int, cohorts => array)
493
 */
494
function enrol_manual_get_potential_cohorts($context, $enrolid, $search = '', $page = 0, $perpage = 25, $addedenrollment = 0) {
495
    global $CFG;
496
    require_once($CFG->dirroot . '/cohort/lib.php');
497
 
498
    $allcohorts = cohort_get_available_cohorts($context, COHORT_WITH_NOTENROLLED_MEMBERS_ONLY, 0, 0, $search);
499
    $totalcohorts = count($allcohorts);
500
    $cohorts = array();
501
    $cnt = 0;
502
    foreach ($allcohorts as $c) {
503
        if ($cnt >= $page * $perpage && (!$perpage || $cnt < ($page+1)*$perpage)) {
504
            $cohorts[] = (object)array(
505
                'id' => $c->id,
506
                'name' => format_string($c->name, true, array('context' => $c->contextid)),
507
                'cnt' => $c->memberscnt - $c->enrolledcnt
508
            );
509
        }
510
        $cnt++;
511
    }
512
    return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts);
513
}