• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apsolu / enrol_select / 18527376245

15 Oct 2025 11:20AM UTC coverage: 13.78% (-0.1%) from 13.886%
18527376245

push

github

jboulen
refactor(manage): réorganise l'ordre de déclaration des variables

144 of 1045 relevant lines covered (13.78%)

0.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

32.11
/lib.php
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
 * Select enrolment plugin.
19
 *
20
 * @package    enrol_select
21
 * @copyright  2016 Université Rennes 2 <dsi-contact@univ-rennes2.fr>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24

25
defined('MOODLE_INTERNAL') || die();
26

27
use local_apsolu\core\federation\course as FederationCourse;
28

29
require_once($CFG->dirroot . '/enrol/select/locallib.php');
×
30
require_once($CFG->dirroot . '/local/apsolu/locallib.php');
×
31

32
/**
33
 * Classe principale du module enrol_select.
34
 *
35
 * @package    enrol_select
36
 * @copyright  2016 Université Rennes 2 <dsi-contact@univ-rennes2.fr>
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
#[\AllowDynamicProperties]
40
class enrol_select_plugin extends enrol_plugin {
41
    /**
42
     * Code du statut accepté.
43
     */
44
    const ACCEPTED = '0';
45

46
    /**
47
     * Code du statut de la liste principale.
48
     */
49
    const MAIN = '2';
50

51
    /**
52
     * Code du statut de la liste secondaire.
53
     */
54
    const WAIT = '3';
55

56
    /**
57
     * Code du statut désinscrit.
58
     */
59
    const DELETED = '4';
60

61
    /** @var array Tableau indexé avec les constantes de classe ACCEPTED, MAIN, WAIT et DELETED. */
62
    public static $states = [
63
        self::ACCEPTED => 'accepted',
64
        self::MAIN => 'main',
65
        self::WAIT => 'wait',
66
        self::DELETED => 'deleted',
67
    ];
68

69
    /**
70
     * Retourne la chaine de caractères correspondant à une constante.
71
     *
72
     * @param int|string  $status Valeur correspondant à une des constantes de classe (ACCEPTED, MAIN, WAIT et DELETED).
73
     * @param null|string $type   Valeur pouvant être null, abbr ou short.
74
     *
75
     * @return string|false Retourne false si le $status n'est pas correct.
76
     */
77
    public static function get_enrolment_list_name($status, $type = null) {
78
        if ($type !== null) {
×
79
            $type = '_' . $type;
×
80
        }
81

82
        switch ($status) {
83
            case self::ACCEPTED:
84
            case self::MAIN:
×
85
            case self::WAIT:
×
86
            case self::DELETED:
×
87
                return get_string(self::$states[$status] . '_list' . $type, 'enrol_select');
×
88
        }
89

90
        return false;
×
91
    }
92

93
    /**
94
     * Returns name of this enrol plugin.
95
     *
96
     * @return string
97
     */
98
    public function get_name() {
99
        // Second word in class is always enrol name, sorry, no fancy plugin names with _.
100
        return 'select';
×
101
    }
102

103
    /**
104
     * Returns edit icons for the page with list of instances.
105
     *
106
     * @param stdClass $instance
107
     *
108
     * @return array
109
     */
110
    public function get_action_icons(stdClass $instance) {
111
        global $OUTPUT;
112

113
        if ($instance->enrol !== 'select') {
×
114
            throw new coding_exception('invalid enrol instance!');
×
115
        }
116
        $context = context_course::instance($instance->courseid);
×
117

118
        $icons = [];
×
119

120
        if (has_capability('enrol/select:enrol', $context) || has_capability('enrol/select:unenrol', $context)) {
×
121
            $managelink = new moodle_url("/enrol/select/manage.php", ['enrolid' => $instance->id]);
×
122

123
            $label = get_string('enrolusers', 'enrol_manual');
×
124
            $pixicon = new pix_icon('t/enrolusers', $label, 'core', ['class' => 'iconsmall']);
×
125
            $icons[] = $OUTPUT->action_icon($managelink, $pixicon);
×
126
        }
127

128
        if (has_capability('enrol/select:config', $context)) {
×
129
            $editlink = new moodle_url("/enrol/select/edit.php", ['courseid' => $instance->courseid, 'id' => $instance->id]);
×
130
            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon(
×
131
                't/edit',
×
132
                get_string('edit'),
×
133
                'core',
×
134
                ['class' => 'iconsmall']
×
135
            ));
×
136
        }
137

138
        return $icons;
×
139
    }
140

141
    /**
142
     * Méthode permettant de récupérer la liste des utilisateurs dont l'inscription est valide/autorisée pour une péride donnée.
143
     *
144
     * @param int|string $courseid  Identifiant du cours.
145
     * @param int|null   $timestart Horodatage UNIX représentant la date de début de la période à valider.
146
     * @param int|null   $timeend   Horodatage UNIX représentant la date de fin de la période à valider.
147
     *
148
     * @return array Tableau contenant les utilisateurs indéxé par userid.
149
     */
150
    public static function get_authorized_registred_users($courseid, $timestart = null, $timeend = null) {
151
        global $DB;
152

153
        if ($timestart === null) {
×
154
            $timestart = time();
×
155
        }
156

157
        if ($timeend === null) {
×
158
            $timeend = time();
×
159
        }
160

161
        $sql = "SELECT DISTINCT u.*" .
×
162
            " FROM {user} u" .
×
163
            " JOIN {user_enrolments} ue ON u.id = ue.userid" .
×
164
            " JOIN {enrol} e ON e.id = ue.enrolid AND e.enrol = 'select'" .
×
165
            " JOIN {role_assignments} ra ON u.id = ra.userid AND e.id = ra.itemid AND ra.component = 'enrol_select'" .
×
166
            " JOIN {role} r ON r.id = ra.roleid" .
×
167
            " JOIN {context} ctx ON ra.contextid = ctx.id AND ctx.instanceid = e.courseid" .
×
168
            " JOIN {cohort_members} cm ON u.id = cm.userid" .
×
169
            " JOIN {enrol_select_roles} esr ON r.id = esr.roleid AND e.id = esr.enrolid" .
×
170
            " JOIN {enrol_select_cohorts} esc ON cm.cohortid = esc.cohortid AND e.id = esr.enrolid" .
×
171
            " JOIN {apsolu_colleges_members} acm ON cm.cohortid = acm.cohortid" .
×
172
            " JOIN {apsolu_colleges} ac ON ra.roleid = ac.roleid AND acm.collegeid = ac.id" .
×
173
            " WHERE e.status = 0" . // Only active enrolments.
×
174
            " AND ue.status = 0" .
×
175
            " AND (ue.timestart < :timestart OR ue.timestart = 0)" .
×
176
            " AND (ue.timeend > :timeend OR ue.timeend = 0)" .
×
177
            " AND e.courseid = :courseid" .
×
178
            " AND ctx.contextlevel = 50" . // Course level.
×
179
            " AND r.archetype = 'student'";
×
180

181
        $params = [];
×
182
        $params['courseid'] = $courseid;
×
183
        $params['timestart'] = $timestart;
×
184
        $params['timeend'] = $timeend;
×
185

186
        return $DB->get_records_sql($sql, $params);
×
187
    }
188

189
    /**
190
     * This returns false for backwards compatibility, but it is really recommended.
191
     *
192
     * @since Moodle 3.1
193
     * @return boolean
194
     */
195
    public function use_standard_editing_ui() {
196
        // TODO: mettre à true pour afficher les méthodes dans le menu déroulant.
197
        return false;
×
198
    }
199

200
    /**
201
     * Add elements to the edit instance form.
202
     *
203
     * @param stdClass $instance
204
     * @param MoodleQuickForm $mform
205
     * @param context $context
206
     * @return bool
207
     */
208
    public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
209
        // TODO: ne pas utiliser ce hook moche.
210
        redirect(new moodle_url('/enrol/select/edit.php', ['courseid' => $instance->courseid, 'id' => $instance->id]));
×
211
    }
212

213
    /**
214
     * Perform custom validation of the data used to edit the instance.
215
     *
216
     * @param array $data array of ("fieldname"=>value) of submitted data
217
     * @param array $files array of uploaded files "element_name"=>tmp_file_path
218
     * @param object $instance The instance loaded from the DB
219
     * @param context $context The context of the instance we are editing
220
     * @return array of "element_name"=>"error_description" if there are errors,
221
     *         or an empty array if everything is OK.
222
     * @return void
223
     */
224
    public function edit_instance_validation($data, $files, $instance, $context) {
225
        // TODO.
226
    }
×
227

228
    /**
229
     * Returns link to page which may be used to add new instance of enrolment plugin in course.
230
     *
231
     * @param int $courseid
232
     *
233
     * @return moodle_url page url
234
     */
235
    public function get_newinstance_link($courseid) {
236
        $context = context_course::instance($courseid, MUST_EXIST);
×
237

238
        if (!has_capability('moodle/course:enrolconfig', $context) || !has_capability('enrol/select:config', $context)) {
×
239
            return null;
×
240
        }
241
        // Multiple instances supported - different roles with different password.
242
        return new moodle_url('/enrol/select/edit.php', ['courseid' => $courseid]);
×
243
    }
244

245
    /**
246
     * Returns defaults for new instances.
247
     *
248
     * @return array
249
     */
250
    public function get_instance_defaults() {
251
        $instance = get_config('enrol_select');
×
252

253
        if (isset($instance->default_roles) === false) {
×
254
            $instance->default_cohorts = '';
×
255
            $instance->default_roles = 5;
×
256
            $instance->default_cards = '';
×
257
            $instance->default_customint1 = 20;
×
258
            $instance->default_customint2 = 10;
×
259
            $instance->default_customint3 = 0;
×
260
            $instance->default_customdec1 = 0;
×
261
            $instance->default_customchar1 = 0;
×
262
            $instance->default_customchar2 = 0;
×
263
            $instance->default_customchar3 = self::MAIN;
×
264
            $instance->default_customtext1 = '';
×
265
            $instance->default_customtext2 = '';
×
266
            $instance->default_customtext3 = '';
×
267
        }
268

269
        $fields = [];
×
270
        $fields['status'] = ENROL_INSTANCE_ENABLED; // Enable method or not.
×
271
        $fields['cohorts'] = explode(',', $instance->default_cohorts); // Cohortes par défaut.
×
272
        $fields['roles'] = explode(',', $instance->default_roles); // Rôles par défaut.
×
273
        $fields['cards'] = explode(',', $instance->default_cards); // Paiements par défaut.
×
274
        $fields['customint1'] = $instance->default_customint1; // Maximum de place sur la liste principale.
×
275
        $fields['customint2'] = $instance->default_customint2; // Maximum de place sur la liste d'attente.
×
276
        $fields['customint3'] = $instance->default_customint3; // Activer les quotas.
×
277
        $fields['customint4'] = 0; // Reenrol start date.
×
278
        $fields['customint5'] = 0; // Reenrol end date.
×
279
        $fields['customint6'] = 0; // Reenrol select_enrol instance.
×
280
        $fields['customint7'] = 0; // Course start date.
×
281
        $fields['customint8'] = 0; // Course end date.
×
282
        $fields['customdec1'] = $instance->default_customdec1; // Délai de paiement.
×
283
        $fields['customchar1'] = $instance->default_customchar1; // Type de calendrier.
×
284
        $fields['customchar2'] = $instance->default_customchar2; // Remontée de liste automatique.
×
285
        $fields['customchar3'] = $instance->default_customchar3; // Liste sur laquelle inscrire les étudiants.
×
286
        $fields['customtext1'] = $instance->default_customtext1; // Message de bienvenue pour les inscrits sur liste des acceptés.
×
287
        $fields['customtext2'] = $instance->default_customtext2; // Message de bienvenue pour les inscrits sur liste principale.
×
288
        $fields['customtext3'] = $instance->default_customtext3; // Message de bienvenue pour les inscrits sur liste complémentaire.
×
289

290
        return $fields;
×
291
    }
292

293
    /**
294
     * Is it possible to hide/show enrol instance via standard UI?
295
     *
296
     * @param stdClass $instance
297
     *
298
     * @return bool
299
     */
300
    public function can_hide_show_instance($instance) {
301
        $context = context_course::instance($instance->courseid);
×
302

303
        return has_capability('enrol/select:config', $context);
×
304
    }
305

306
    /**
307
     * Return true if we can add a new instance to this course.
308
     *
309
     * @param int $courseid
310
     *
311
     * @return boolean
312
     */
313
    public function can_add_instance($courseid) {
314
        global $DB;
315

316
        $context = context_course::instance($courseid, MUST_EXIST);
×
317
        if (!has_capability('moodle/course:enrolconfig', $context) || !has_capability('enrol/manual:config', $context)) {
×
318
            return false;
×
319
        }
320

321
        if ($DB->record_exists('enrol', ['courseid' => $courseid, 'enrol' => 'manual'])) {
×
322
            // Multiple instances not supported.
323
            return false;
×
324
        }
325

326
        return true;
×
327
    }
328

329
    /**
330
     * Is it possible to delete enrol instance via standard UI?
331
     *
332
     * @param object $instance
333
     *
334
     * @return bool
335
     */
336
    public function can_delete_instance($instance) {
337
        $context = context_course::instance($instance->courseid);
×
338
        return has_capability('enrol/select:config', $context);
×
339
    }
340

341
    /**
342
     * Retourne le code de la liste dans laquelle sera enregistré le prochain inscrit.
343
     *
344
     * @param object $instance Objet de l'instance de la méthode d'inscription.
345
     * @param object $user     Objet représentant le prochain utilisateur inscrit.
346
     *
347
     * @return string|false Retourne false si il n'y a plus de place cette méthode d'inscription par voeux.
348
     */
349
    public function get_available_status($instance, $user) {
350
        global $DB;
351

352
        if (empty($instance->customint3) === true) {
4✔
353
            // Lorsque les quota ne sont pas activés, on retourne le code de la liste principale.
354
            return self::get_default_enrolment_list($instance);
4✔
355
        }
356

357
        // Détermine si l'utilisateur est déjà inscrit sur cette instance.
358
        $userenrolment = $DB->get_record('user_enrolments', ['enrolid' => $instance->id, 'userid' => $user->id]);
4✔
359
        if ($userenrolment !== false) {
4✔
360
            // Retourne la liste d'inscription actuelle de l'utilisateur.
361
            return $userenrolment->status;
4✔
362
        }
363

364
        // Détermine si il y a déjà des utilisateurs sur liste complémentaire.
365
        $params = ['enrolid' => $instance->id, 'status' => self::WAIT];
4✔
366
        $waitlistenrolements = $DB->get_records('user_enrolments', $params, '', 'userid');
4✔
367
        $this->count_wait_list_enrolements = count($waitlistenrolements);
4✔
368

369
        if (isset($user, $waitlistenrolements[$user->id])) {
4✔
370
            unset($waitlistenrolements[$user->id]);
×
371
            $countwaitlistenrolements = $this->count_wait_list_enrolements - 1;
×
372
        } else {
373
            $countwaitlistenrolements = $this->count_wait_list_enrolements;
4✔
374
        }
375

376
        if ($countwaitlistenrolements >= $instance->customint2 && empty($instance->customint2) === false) {
4✔
377
            // Il n'y a plus de place disponible sur la liste complémentaire
378
            // et les quotas sont définis pour la liste complémentaire.
379
            return false;
4✔
380
        }
381

382
        if ($countwaitlistenrolements !== 0) {
4✔
383
            // Il y a déjà des utilisateurs sur liste complémentaire. On est sûr qu'il reste de la place uniquement ici.
384
            return self::WAIT;
4✔
385
        }
386

387
        // Détermine si il y a déjà des utilisateurs sur la liste des acceptés et la liste principale.
388
        $sql = "SELECT userid" .
4✔
389
            " FROM {user_enrolments}" .
4✔
390
            " WHERE enrolid = :enrolid" .
4✔
391
            " AND status IN (:accepted, :main)";
4✔
392
        $params = ['enrolid' => $instance->id, 'accepted' => self::ACCEPTED, 'main' => self::MAIN];
4✔
393
        $mainlistenrolements = $DB->get_records_sql($sql, $params);
4✔
394
        $this->count_main_list_enrolements = count($mainlistenrolements);
4✔
395

396
        if (isset($user, $mainlistenrolements[$user->id])) {
4✔
397
            unset($mainlistenrolements[$user->id]);
×
398
            $countmainlistenrolements = $this->count_main_list_enrolements - 1;
×
399
        } else {
400
            $countmainlistenrolements = $this->count_main_list_enrolements;
4✔
401
        }
402

403
        if ($countmainlistenrolements < $instance->customint1 && empty($instance->customint1) === false) {
4✔
404
            // Il reste des places disponibles sur liste principale et les quotas sont définis pour la liste principale.
405
            return self::get_default_enrolment_list($instance);
4✔
406
        }
407

408
        // Cas où la liste principale est pleine et la liste complémentaire est vide.
409
        if (empty($instance->customint2) === false) {
4✔
410
            // Si le quota sur la liste complémentaire n'est pas vide.
411
            return self::WAIT;
4✔
412
        }
413

414
        // Il n'y a pas de liste complémentaire. Il n'est plus possible de s'inscrire.
415
        return false;
4✔
416
    }
417

418
    /**
419
     * Retourne le code de la liste sur laquelle est inscrit l'utilisateur par défaut.
420
     *
421
     * @param object $instance Objet de l'instance de la méthode d'inscription.
422
     *
423
     * @return int Retourne soit self::ACCEPTED, soit self::MAIN.
424
     */
425
    public static function get_default_enrolment_list($instance) {
426
        if ($instance->customchar3 === self::ACCEPTED) {
4✔
427
            return self::ACCEPTED;
4✔
428
        }
429

430
        return self::MAIN;
4✔
431
    }
432

433
    /**
434
     * Retourne les rôles disponibles pour une méthode d'inscription donnée et un contexte.
435
     *
436
     * @param object $instance Objet de l'instance de la méthode d'inscription
437
     * @param object $context  Objet représentant un contexte.
438
     *
439
     * @return array Retourne un tableau de rôles.
440
     */
441
    public function get_roles($instance, $context) {
442
        global $DB;
443

444
        $roles = $DB->get_records('enrol_select_roles', ['enrolid' => $instance->id], '', 'roleid');
×
445
        foreach (get_assignable_roles($context, ROLENAME_BOTH) as $id => $role) {
×
446
            if (!isset($roles[$id])) {
×
447
                unset($roles[$id]);
×
448
            } else {
449
                $roles[$id]->id = $id;
×
450
                $roles[$id]->name = $role;
×
451
            }
452
        }
453

454
        $roles = array_values($roles);
×
455

456
        return $roles;
×
457
    }
458

459
    /**
460
     * Retourne le rôle d'un utilisateur pour une méthode d'inscription donnée.
461
     *
462
     * @param object $instance Objet de l'instance de la méthode d'inscription
463
     * @param int    $userid   Identifiant de l'utilisateur. Si il n'est pas fourni,
464
     *                         c'est l'identifiant de l'utilisateur courant qui sera utilisé.
465
     *
466
     * @return object|false Retourne un object du rôle ou false si l'utilisateur n'est pas inscrit via cette méthode.
467
     */
468
    public function get_user_role($instance, $userid = null) {
469
        global $DB, $USER;
470

471
        if ($userid === null) {
×
472
            $userid = $USER->id;
×
473
        }
474

475
        $sql = "SELECT r.*" .
×
476
            " FROM {role} r" .
×
477
            " JOIN {role_assignments} ra ON r.id = ra.roleid" .
×
478
            " JOIN {context} ctx ON ctx.id = ra.contextid" .
×
479
            " JOIN {enrol} e ON ctx.instanceid = e.courseid AND e.id = ra.itemid" .
×
480
            " JOIN {user_enrolments} ue ON e.id = ue.enrolid AND ue.userid = ra.userid" .
×
481
            " WHERE e.id = :enrolid" .
×
482
            " AND e.enrol = 'select'" .
×
483
            " AND e.status = 0" . // Active.
×
484
            " AND ue.userid = :userid" .
×
485
            " AND ctx.contextlevel = 50";
×
486
        $params = ['enrolid' => $instance->id, 'userid' => $userid];
×
487

488
        $roles = role_fix_names($DB->get_records_sql($sql, $params));
×
489

490
        return current($roles);
×
491
    }
492

493
    /**
494
     * Retourne les rôles disponibles pour un utilisateur et une méthode d'inscription donnée.
495
     *
496
     * @param object $instance Objet de l'instance de la méthode d'inscription
497
     * @param int    $userid   Identifiant de l'utilisateur. Si il n'est pas fourni,
498
     *                         c'est l'identifiant de l'utilisateur courant qui sera utilisé.
499
     *
500
     * @return array Retourne un tableau de rôles.
501
     */
502
    public function get_available_user_roles($instance, $userid = null) {
503
        global $DB, $USER;
504

505
        if ($userid === null) {
×
506
            $userid = $USER->id;
×
507
        }
508

509
        $sql = "SELECT DISTINCT r.*
×
510
                  FROM {role} r
511
                  JOIN {enrol_select_roles} esr ON r.id = esr.roleid
512
                  JOIN {enrol} e ON e.id = esr.enrolid
513
                  JOIN {enrol_select_cohorts} esc ON e.id = esc.enrolid
514
                  JOIN {cohort_members} cm ON cm.cohortid = esc.cohortid
515
                  JOIN {apsolu_colleges_members} acm ON acm.cohortid = cm.cohortid
516
                  JOIN {apsolu_colleges} ac ON ac.id = acm.collegeid AND r.id = ac.roleid
517
                 WHERE e.id = :enrolid
518
                   AND e.enrol = 'select'
519
                   AND e.status = 0  -- Active.
520
                   AND cm.userid = :userid
521
              ORDER BY r.sortorder";
×
522
        $params = ['enrolid' => $instance->id, 'userid' => $userid];
×
523

524
        return role_fix_names($DB->get_records_sql($sql, $params));
×
525
    }
526

527
    /**
528
     * Fonction à documenter (TODO).
529
     *
530
     * @param object      $instance Objet de l'instance de la méthode d'inscription
531
     * @param null|object $user     Identifiant de l'utilisateur. Si il n'est pas fourni,
532
     *                              c'est l'identifiant de l'utilisateur courant qui sera utilisé.
533
     *
534
     * @return void.
535
     */
536
    public function set_available_status($instance, $user = null) {
537
        global $DB;
538

539
        debugging(sprintf('%s() is deprecated. Please see' .
×
540
            ' enrol_select_plugin::get_available_status() method instead.', __METHOD__), DEBUG_DEVELOPER);
×
541

542
        $this->available_status = [];
×
543

544
        // Check main list.
545
        $sql = "SELECT userid" .
×
546
            " FROM {user_enrolments}" .
×
547
            " WHERE enrolid = :enrolid" .
×
548
            " AND status IN (0, 2)";
×
549
        $mainlistenrolements = $DB->get_records_sql($sql, ['enrolid' => $instance->id]);
×
550
        $this->count_main_list_enrolements = count($mainlistenrolements);
×
551

552
        if (isset($user, $mainlistenrolements[$user->id])) {
×
553
            unset($mainlistenrolements[$user->id]);
×
554
            $countmainlistenrolements = $this->count_main_list_enrolements - 1;
×
555
        } else {
556
            $countmainlistenrolements = $this->count_main_list_enrolements;
×
557
        }
558

559
        if ($countmainlistenrolements < $instance->customint1) {
×
560
            // Some slots are available on main list.
561
            $this->available_status[] = '2';
×
562
        }
563

564
        // Check wait list.
565
        $params = ['enrolid' => $instance->id, 'status' => self::WAIT];
×
566
        $waitlistenrolements = $DB->get_records('user_enrolments', $params, '', 'userid');
×
567
        $this->count_wait_list_enrolements = count($waitlistenrolements);
×
568

569
        if (isset($user, $waitlistenrolements[$user->id])) {
×
570
            unset($waitlistenrolements[$user->id]);
×
571
            $countwaitlistenrolements = $this->count_wait_list_enrolements - 1;
×
572
        } else {
573
            $countwaitlistenrolements = $this->count_wait_list_enrolements;
×
574
        }
575

576
        if ($countwaitlistenrolements < $instance->customint2) {
×
577
            // Some slots are available on wait list.
578
            $this->available_status[] = '3';
×
579
        }
580
    }
581

582
    /**
583
     * Détermine si les inscriptions sont ouvertes.
584
     *
585
     * @param object $instance Objet de l'instance de la méthode d'inscription
586
     *
587
     * @return bool Vrai si les inscriptions sont ouvertes.
588
     */
589
    public function is_enrol_period_active($instance) {
590
        $today = time();
×
591

592
        $opening = ($instance->enrolstartdate === '0' || $instance->enrolstartdate <= $today);
×
593
        $closing = ($instance->enrolenddate === '0' || $instance->enrolenddate >= $today);
×
594

595
        return ($opening && $closing);
×
596
    }
597

598
    /**
599
     * Détermine si un utilisateur peut s'inscrire à une instance avec un rôle donné.
600
     *
601
     * @param object     $instance Objet de l'instance de la méthode d'inscription.
602
     * @param object     $user     Objet représentant l'utilisateur.
603
     * @param int|string $roleid   Identifiant d'un rôle.
604
     *
605
     * @return bool Vrai si les inscriptions sont ouvertes.
606
     */
607
    public function can_enrol($instance, $user, $roleid) {
608
        global $CFG, $DB;
609

610
        $today = time();
×
611

612
        // Check opening register period.
613
        if ($instance->enrolstartdate !== '0' && $instance->enrolstartdate > $today) {
×
614
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
615
                debugging($this->get_name() . ' not opened yet.', $level = DEBUG_DEVELOPER);
×
616
            }
617
            return false;
×
618
        }
619

620
        // Check closing register period.
621
        if ($instance->enrolenddate !== '0' && $instance->enrolenddate < $today) {
×
622
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
623
                debugging($this->get_name() . ' already closed.', $level = DEBUG_DEVELOPER);
×
624
            }
625
            return false;
×
626
        }
627

628
        // Check cohorts.
629
        $usercohorts = $DB->get_records('cohort_members', ['userid' => $user->id]);
×
630
        $enrolcohorts = $DB->get_records('enrol_select_cohorts', ['enrolid' => $instance->id], '', 'cohortid');
×
631

632
        $found = false;
×
633
        foreach ($usercohorts as $cohort) {
×
634
            if (isset($enrolcohorts[$cohort->cohortid])) {
×
635
                $found = true;
×
636
                break;
×
637
            }
638
        }
639

640
        if ($found !== true) {
×
641
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
642
                debugging($this->get_name() . ': ' . $user->username . ' and enrol cohort mismatch.', $level = DEBUG_DEVELOPER);
×
643
            }
644
            return false;
×
645
        }
646

647
        $federationcourse = new FederationCourse();
×
648
        if ($instance->courseid === $federationcourse->get_courseid()) {
×
649
            // Bidouille moche pour gérer l'inscription à la FFSU.
650
            return true;
×
651
        }
652

653
        if (isset($CFG->is_siuaps_rennes) === true) {
×
654
            // Dirty hack pour les activités complémentaires !
655
            // À virer, et mettre des auto-inscriptions à la place.
656
            if ($roleid == 5 || in_array($instance->courseid, ['249', '250'], $strict = true) === true) {
×
657
                return true;
×
658
            }
659
        }
660

661
        // Check available slots.
662
        if ($this->get_available_status($instance, $user) === false) {
×
663
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
664
                debugging($this->get_name() . ' n\'a plus aucune place disponible.', $level = DEBUG_DEVELOPER);
×
665
            }
666
            return false;
×
667
        }
668

669
        // Check user limit.
670
        $userchoices = enrol_select_get_sum_user_choices($userid = null, $count = true);
×
671
        $available = false;
×
672
        foreach ($userchoices as $choice) {
×
673
            if ($choice->roleid != $roleid) {
×
674
                continue;
×
675
            }
676

677
            if ($choice->maxwish == 0 || $choice->count < $choice->maxwish) {
×
678
                $available = true;
×
679
                break;
×
680
            }
681
        }
682

683
        if ($available === false) {
×
684
            $parameters = ['userid' => $user->id, 'roleid' => $roleid];
×
685
            $message = get_string('the_user_X_has_reached_their_wish_limit_for_the_role_Y', 'enrol_select', $parameters);
×
686

687
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
688
                debugging($message, $level = DEBUG_DEVELOPER);
×
689
            }
690
            return false;
×
691
        }
692

693
        // Check role.
694
        if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
695
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
696
                debugging($this->get_name() . ': roleid #' . $roleid . ' is not available.', $level = DEBUG_DEVELOPER);
×
697
            }
698
            return false;
×
699
        }
700

701
        return true;
×
702
    }
703

704
    /**
705
     * Détermine si un utilisateur peut se réinscrire.
706
     *
707
     * @param object          $instance Objet de l'instance de la méthode d'inscription.
708
     * @param null|int|string $userid   Identifiant d'un utilisateur.
709
     * @param null|int|string $roleid   Identifiant d'un rôle.
710
     *
711
     * @return bool Vrai si les inscriptions sont ouvertes.
712
     */
713
    public function can_reenrol($instance, $userid = null, $roleid = null) {
714
        global $DB, $USER;
715

716
        $today = time();
×
717

718
        if ($userid === null) {
×
719
            $userid = $USER->id;
×
720
        }
721

722
        // Check reenrol enabled.
723
        if (empty($instance->customint6)) {
×
724
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
725
                debugging($this->get_name() . ' reenrol not enabled.', $level = DEBUG_DEVELOPER);
×
726
            }
727
            return false;
×
728
        }
729

730
        // Check reenrol exists.
731
        $enrol = $DB->get_record('enrol', ['id' => $instance->customint6, 'enrol' => 'select']);
×
732
        if ($enrol === false) {
×
733
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
734
                debugging(
×
735
                    $this->get_name() . ' reenrol id #' . $instance->customint6 . ' does not exist',
×
736
                    $level = DEBUG_DEVELOPER
×
737
                );
×
738
            }
739
            return false;
×
740
        }
741

742
        // Check opening reenrol period.
743
        if ($instance->customint4 !== '0' && $instance->customint4 > $today) {
×
744
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
745
                debugging($this->get_name() . ' not opened yet.', $level = DEBUG_DEVELOPER);
×
746
            }
747
            return false;
×
748
        }
749

750
        // Check closing reenrol period.
751
        if ($instance->customint5 !== '0' && $instance->customint5 < $today) {
×
752
            if (defined('BEHAT_SITE_RUNNING') === false) {
×
753
                debugging($this->get_name() . ' already closed.', $level = DEBUG_DEVELOPER);
×
754
            }
755
            return false;
×
756
        }
757

758
        // Check cohorts.
759
        if ($instance->customint3 === '1') {
×
760
            $usercohorts = $DB->get_records('cohort_members', ['userid' => $userid]);
×
761
            $enrolcohorts = $DB->get_records('enrol_select_cohorts', ['enrolid' => $instance->id], '', 'cohortid');
×
762

763
            $found = false;
×
764
            foreach ($usercohorts as $cohort) {
×
765
                if (isset($enrolcohorts[$cohort->cohortid])) {
×
766
                    $found = true;
×
767
                    break;
×
768
                }
769
            }
770

771
            if ($found !== true) {
×
772
                if (defined('BEHAT_SITE_RUNNING') === false) {
×
773
                    debugging($this->get_name() . ': userid #' . $userid . ' and enrol cohort mismatch.', $level = DEBUG_DEVELOPER);
×
774
                }
775
                return false;
×
776
            }
777
        }
778

779
        // We don't check available slots.
780
        // We don't check user limit.
781

782
        // Check role.
783
        if ($roleid !== null) {
×
784
            if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
785
                if (defined('BEHAT_SITE_RUNNING') === false) {
×
786
                    debugging($this->get_name() . ': roleid #' . $roleid . ' is not available.', $level = DEBUG_DEVELOPER);
×
787
                }
788
                return false;
×
789
            }
790
        }
791

792
        return true;
×
793
    }
794

795
    /**
796
     * Méthode permettant l'inscription d'un utilisateur à une instance.
797
     *
798
     * @param stdClass        $instance      Objet de l'instance de la méthode d'inscription.
799
     * @param int|string      $userid        Identifiant d'un utilisateur.
800
     * @param null|int|string $roleid        Identifiant d'un rôle.
801
     * @param int|string      $timestart     Timestamp de début de cours.
802
     * @param int|string      $timeend       Timestamp de fin de cours.
803
     * @param null|int|string $status        État de l'inscription (accepté, liste principale, liste secondaire, supprimé).
804
     * @param null|bool       $recovergrades Récupérer les notes ?
805
     *
806
     * @return void.
807
     */
808
    public function enrol_user(
809
        stdClass $instance,
810
        $userid,
811
        $roleid = null,
812
        $timestart = 0,
813
        $timeend = 0,
814
        $status = null,
815
        $recovergrades = null
816
    ) {
817
        global $DB, $USER;
818

819
        // La méthode parent::enrol_user() ne remplace pas les rôles, mais cumul.
820
        // Il faut donc faire un traitement différent si il s'agit juste d'un changement de rôle.
821
        $enrolled = $DB->get_record('user_enrolments', ['enrolid' => $instance->id, 'userid' => $userid]);
4✔
822
        if ($enrolled === false) {
4✔
823
            if ($timestart === 0) {
4✔
824
                $timestart = $instance->customint7;
4✔
825
            }
826

827
            if ($timeend === 0) {
4✔
828
                $timeend = $instance->customint8;
4✔
829
            }
830

831
            parent::enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status, $recovergrades);
4✔
832

833
            // Ajoute une tâche pour contrôler le paiement après l'inscription.
834
            $instance->customdec1 = intval($instance->customdec1);
4✔
835
            if (empty($instance->customdec1) === false && $status === self::ACCEPTED) {
4✔
836
                $customdata = (object) ['courseid' => $instance->courseid, 'enrolid' => $instance->id];
×
837

838
                $task = new enrol_select\task\check_enrolment_payment();
×
839
                $task->set_next_run_time(time() + $instance->customdec1);
×
840
                $task->set_custom_data($customdata);
×
841
                $task->set_userid($userid);
×
842

843
                core\task\manager::queue_adhoc_task($task);
×
844
            }
845

846
            // Notifie le nouvel inscrit.
847
            if ($userid === $USER->id) {
4✔
848
                $message = '';
4✔
849
                switch ($status) {
850
                    case self::ACCEPTED:
851
                        $message = $instance->customtext1;
4✔
852
                        break;
4✔
853
                    case self::MAIN:
4✔
854
                        $message = $instance->customtext2;
4✔
855
                        break;
4✔
856
                    case self::WAIT:
4✔
857
                        $message = $instance->customtext3;
4✔
858
                        break;
4✔
859
                }
860

861
                if (empty($message) === false) {
4✔
862
                    $course = $DB->get_record('course', ['id' => $instance->courseid]);
4✔
863

864
                    $eventdata = new \core\message\message();
4✔
865
                    $eventdata->name = 'select_notification';
4✔
866
                    $eventdata->component = 'enrol_select';
4✔
867
                    $eventdata->userfrom = get_admin();
4✔
868
                    $eventdata->userto = $userid;
4✔
869
                    $params = format_string($course->fullname, $striplinks = true, $course->id);
4✔
870
                    $eventdata->subject = get_string('enrolment_to', 'enrol_select', $params);
4✔
871
                    $eventdata->fullmessage = $message;
4✔
872
                    $eventdata->fullmessageformat = FORMAT_HTML;
4✔
873
                    $eventdata->fullmessagehtml = $message;
4✔
874
                    $eventdata->smallmessage = '';
4✔
875
                    $eventdata->notification = 1;
4✔
876
                    $eventdata->courseid = $course->id;
4✔
877

878
                    message_send($eventdata);
4✔
879
                }
880
            }
881

882
            return;
4✔
883
        }
884

885
        // Traite le cas où on souhaite juste modifier le statut.
886
        if ($status !== null) {
4✔
887
            $sql = "UPDATE {user_enrolments}" .
4✔
888
                " SET status = :status, timemodified = :now" .
4✔
889
                " WHERE enrolid = :enrolid" .
4✔
890
                " AND userid = :userid";
4✔
891
            $DB->execute($sql, ['status' => $status, 'now' => time(), 'enrolid' => $instance->id, 'userid' => $userid]);
4✔
892
        }
893

894
        // Traite le cas où on souhaite juste modifier le rôle.
895
        if ($roleid !== null) {
4✔
896
            $coursecontext = context_course::instance($instance->courseid);
4✔
897

898
            $sql = "UPDATE {role_assignments}" .
4✔
899
                " SET roleid = :roleid, timemodified = :now" .
4✔
900
                " WHERE component = 'enrol_select'" .
4✔
901
                " AND userid = :userid" .
4✔
902
                " AND contextid = :contextid" .
4✔
903
                " AND itemid= :itemid";
4✔
904
            $params = [
4✔
905
                'roleid' => $roleid,
4✔
906
                'now' => time(),
4✔
907
                'userid' => $userid,
4✔
908
                'contextid' => $coursecontext->id,
4✔
909
                'itemid' => $instance->id,
4✔
910
            ];
4✔
911
            $DB->execute($sql, $params);
4✔
912
        }
913
    }
914

915
    /**
916
     * Méthode permettant de déinscrire un utilisateur d'une instance.
917
     *
918
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
919
     * @param int|string $userid        Identifiant d'un utilisateur.
920
     *
921
     * @return void.
922
     */
923
    public function unenrol_user(stdClass $instance, $userid) {
924
        global $DB;
925

926
        parent::unenrol_user($instance, $userid);
4✔
927

928
        // Si la remontée de liste est activée.
929
        if (empty($instance->customchar2) === false) {
4✔
930
            $this->refill_main_list($instance, $userid);
4✔
931
        }
932

933
        // Si les paiements à l'inscription sont activées.
934
        $instance->customdec1 = intval($instance->customdec1);
4✔
935
        if (empty($instance->customdec1) === false) {
4✔
936
            // On supprime la tâche adhoc associée à l'utilisateur.
937
            $classname = '\enrol_select\task\check_enrolment_payment';
×
938
            $params = ['component' => 'enrol_select', 'classname' => $classname, 'userid' => $userid];
×
939
            $tasks = $DB->get_records('task_adhoc', $params);
×
940
            foreach ($tasks as $taskid => $task) {
×
941
                $customdata = json_decode($task->customdata);
×
942
                if (isset($customdata->enrolid) === false) {
×
943
                    continue;
×
944
                }
945

946
                if ($customdata->enrolid !== $instance->id) {
×
947
                    continue;
×
948
                }
949

950
                $DB->delete_records('task_adhoc', ['id' => $taskid]);
×
951
            }
952
        }
953
    }
954

955
    /**
956
     * Réorganise la liste d'inscription principale.
957
     *
958
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
959
     * @param int|string $userid        Identifiant d'un utilisateur.
960
     *
961
     * @return void.
962
     */
963
    public function refill_main_list(stdClass $instance, $userid) {
964
        global $DB, $USER;
965

966
        if ($this->is_enrol_period_active($instance) === false) {
4✔
967
            // On ne réalimente pas la liste principale si les inscriptions sont closes.
968
            return;
4✔
969
        }
970

971
        if ($USER->id !== $userid) {
4✔
972
            // L'utilisateur courant n'est pas l'utilisateur à désinscrire.
973
            // Il s'agit probablement d'un enseignant dans la partie management.
974
            // On ne provoque pas la réalimentation de la liste principale.
975
            return;
4✔
976
        }
977

978
        if (empty($instance->customint3) === true) {
4✔
979
            // Les quotas ne sont pas activés pour ce cours.
980
            return;
4✔
981
        }
982

983
        $sql = "SELECT COUNT(*) FROM {user_enrolments} WHERE enrolid = :enrolid AND status IN (:main, :accepted)";
4✔
984
        $params = ['enrolid' => $instance->id, 'main' => self::MAIN, 'accepted' => self::ACCEPTED];
4✔
985
        $countmain = $DB->count_records_sql($sql, $params);
4✔
986
        if ($countmain >= $instance->customint1) {
4✔
987
            // La liste principale (et des acceptés) est déjà pleine.
988
            return;
4✔
989
        }
990

991
        $countwait = $DB->count_records('user_enrolments', ['enrolid' => $instance->id, 'status' => self::WAIT]);
4✔
992
        if ($countwait === 0) {
4✔
993
            // La liste complémentaire est vide.
994
            return;
4✔
995
        }
996

997
        // Détermine le nombre d'inscription à transférer de la liste complémentaire à la liste principale.
998
        $promote = $instance->customint1 - $countmain;
4✔
999

1000
        // Récupère les utilisateurs sur liste complémentaire par ordre d'inscription.
1001
        $params = ['enrolid' => $instance->id, 'status' => self::WAIT];
4✔
1002
        $waitingusers = $DB->get_records('user_enrolments', $params, $sort = 'timecreated ASC');
4✔
1003

1004
        $course = $DB->get_record('course', ['id' => $instance->courseid], '*', MUST_EXIST);
4✔
1005
        foreach ($waitingusers as $user) {
4✔
1006
            $user->status = self::MAIN;
4✔
1007
            $DB->update_record('user_enrolments', $user);
4✔
1008

1009
            // Notifie l'utilisateur sur liste d'attente qui vient d'être basculé sur liste principale.
1010
            $eventdata = new \core\message\message();
4✔
1011
            $eventdata->courseid = $course->id;
4✔
1012
            $eventdata->component = 'enrol_select';
4✔
1013
            $eventdata->name = 'select_notification';
4✔
1014
            $eventdata->userfrom = core_user::get_noreply_user();
4✔
1015
            $eventdata->userto = $DB->get_record('user', ['id' => $user->userid]);
4✔
1016
            $eventdata->subject = get_string('enrolcoursesubject', 'enrol_select', $course);
4✔
1017
            $eventdata->fullmessage = get_string('message_promote', 'enrol_select');
4✔
1018
            $eventdata->fullmessageformat = FORMAT_PLAIN;
4✔
1019
            $eventdata->fullmessagehtml = '';
4✔
1020
            $eventdata->smallmessage = '';
4✔
1021
            $eventdata->notification = 1;
4✔
1022

1023
            message_send($eventdata);
4✔
1024

1025
            $promote--;
4✔
1026
            if ($promote === 0) {
4✔
1027
                break;
4✔
1028
            }
1029
        }
1030
    }
1031
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc