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

apsolu / enrol_select / 14264379215

03 Apr 2025 10:00AM UTC coverage: 14.272% (+0.1%) from 14.132%
14264379215

push

github

jboulen
fix(enrol): utilise le champ 'sortorder' de la table 'role' pour trier les rôles à l'affichage

0 of 2 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

144 of 1009 relevant lines covered (14.27%)

0.43 hits per line

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

33.68
/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('t/edit', get_string('edit'), 'core',
×
131
                ['class' => 'iconsmall']));
×
132
        }
133

134
        return $icons;
×
135
    }
136

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

149
        if ($timestart === null) {
×
150
            $timestart = time();
×
151
        }
152

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

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

177
        $params = [];
×
178
        $params['courseid'] = $courseid;
×
179
        $params['timestart'] = $timestart;
×
180
        $params['timeend'] = $timeend;
×
181

182
        return $DB->get_records_sql($sql, $params);
×
183
    }
184

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

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

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

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

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

241
    /**
242
     * Returns defaults for new instances.
243
     *
244
     * @return array
245
     */
246
    public function get_instance_defaults() {
247
        $instance = get_config('enrol_select');
×
248

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

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

286
        return $fields;
×
287
    }
288

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

299
        return has_capability('enrol/select:config', $context);
×
300
    }
301

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

312
        $context = context_course::instance($courseid, MUST_EXIST);
×
313
        if (!has_capability('moodle/course:enrolconfig', $context) || !has_capability('enrol/manual:config', $context)) {
×
314
            return false;
×
315
        }
316

317
        if ($DB->record_exists('enrol', ['courseid' => $courseid, 'enrol' => 'manual'])) {
×
318
            // Multiple instances not supported.
319
            return false;
×
320
        }
321

322
        return true;
×
323
    }
324

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

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

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

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

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

365
        if (isset($user, $waitlistenrolements[$user->id])) {
3✔
366
            unset($waitlistenrolements[$user->id]);
×
367
            $countwaitlistenrolements = $this->count_wait_list_enrolements - 1;
×
368
        } else {
369
            $countwaitlistenrolements = $this->count_wait_list_enrolements;
3✔
370
        }
371

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

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

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

392
        if (isset($user, $mainlistenrolements[$user->id])) {
3✔
393
            unset($mainlistenrolements[$user->id]);
×
394
            $countmainlistenrolements = $this->count_main_list_enrolements - 1;
×
395
        } else {
396
            $countmainlistenrolements = $this->count_main_list_enrolements;
3✔
397
        }
398

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

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

410
        // Il n'y a pas de liste complémentaire. Il n'est plus possible de s'inscrire.
411
        return false;
3✔
412
    }
413

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

426
        return self::MAIN;
3✔
427
    }
428

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

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

450
        $roles = array_values($roles);
×
451

452
        return $roles;
×
453
    }
454

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

467
        if ($userid === null) {
×
468
            $userid = $USER->id;
×
469
        }
470

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

484
        $roles = role_fix_names($DB->get_records_sql($sql, $params));
×
485

486
        return current($roles);
×
487
    }
488

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

501
        if ($userid === null) {
×
502
            $userid = $USER->id;
×
503
        }
504

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

520
        return role_fix_names($DB->get_records_sql($sql, $params));
×
521
    }
522

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

535
        debugging(sprintf('%s() is deprecated. Please see'.
×
536
            ' enrol_select_plugin::get_available_status() method instead.', __METHOD__), DEBUG_DEVELOPER);
×
537

538
        $this->available_status = [];
×
539

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

548
        if (isset($user, $mainlistenrolements[$user->id])) {
×
549
            unset($mainlistenrolements[$user->id]);
×
550
            $countmainlistenrolements = $this->count_main_list_enrolements - 1;
×
551
        } else {
552
            $countmainlistenrolements = $this->count_main_list_enrolements;
×
553
        }
554

555
        if ($countmainlistenrolements < $instance->customint1) {
×
556
            // Some slots are available on main list.
557
            $this->available_status[] = '2';
×
558
        }
559

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

565
        if (isset($user, $waitlistenrolements[$user->id])) {
×
566
            unset($waitlistenrolements[$user->id]);
×
567
            $countwaitlistenrolements = $this->count_wait_list_enrolements - 1;
×
568
        } else {
569
            $countwaitlistenrolements = $this->count_wait_list_enrolements;
×
570
        }
571

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

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

588
        $opening = ($instance->enrolstartdate === '0' || $instance->enrolstartdate <= $today);
×
589
        $closing = ($instance->enrolenddate === '0' || $instance->enrolenddate >= $today);
×
590

591
        return ($opening && $closing);
×
592
    }
593

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

606
        $today = time();
×
607

608
        // Check opening register period.
609
        if ($instance->enrolstartdate !== '0' && $instance->enrolstartdate > $today) {
×
610
            debugging($this->get_name().' not opened yet.', $level = DEBUG_DEVELOPER);
×
611
            return false;
×
612
        }
613

614
        // Check closing register period.
615
        if ($instance->enrolenddate !== '0' && $instance->enrolenddate < $today) {
×
616
            debugging($this->get_name().' already closed.', $level = DEBUG_DEVELOPER);
×
617
            return false;
×
618
        }
619

620
        // Check cohorts.
621
        $usercohorts = $DB->get_records('cohort_members', ['userid' => $user->id]);
×
622
        $enrolcohorts = $DB->get_records('enrol_select_cohorts', ['enrolid' => $instance->id], '', 'cohortid');
×
623

624
        $found = false;
×
625
        foreach ($usercohorts as $cohort) {
×
626
            if (isset($enrolcohorts[$cohort->cohortid])) {
×
627
                $found = true;
×
628
                break;
×
629
            }
630
        }
631

632
        if ($found !== true) {
×
633
            debugging($this->get_name().': '.$user->username.' and enrol cohort mismatch.', $level = DEBUG_DEVELOPER);
×
634
            return false;
×
635
        }
636

637
        $federationcourse = new FederationCourse();
×
638
        if ($instance->courseid === $federationcourse->get_courseid()) {
×
639
            // Bidouille moche pour gérer l'inscription à la FFSU.
640
            return true;
×
641
        }
642

643
        if (isset($CFG->is_siuaps_rennes) === true) {
×
644
            // Dirty hack pour les activités complémentaires !
645
            // À virer, et mettre des auto-inscriptions à la place.
646
            if ($roleid == 5 || in_array($instance->courseid, ['249', '250'], $strict = true) === true) {
×
647
                return true;
×
648
            }
649
        }
650

651
        // Check available slots.
652
        if ($this->get_available_status($instance, $user) === false) {
×
653
            debugging($this->get_name().' n\'a plus aucune place disponible.', $level = DEBUG_DEVELOPER);
×
654
            return false;
×
655
        }
656

657
        // Check user limit.
658
        $userchoices = enrol_select_get_sum_user_choices($userid = null, $count = true);
×
659
        $available = false;
×
660
        foreach ($userchoices as $choice) {
×
661
            if ($choice->roleid != $roleid) {
×
662
                continue;
×
663
            }
664

665
            if ($choice->maxwish == 0 || $choice->count < $choice->maxwish) {
×
666
                $available = true;
×
667
                break;
×
668
            }
669
        }
670

671
        if ($available === false) {
×
672
            $parameters = ['userid' => $user->id, 'roleid' => $roleid];
×
673
            $message = get_string('the_user_X_has_reached_their_wish_limit_for_the_role_Y', 'enrol_select', $parameters);
×
674

675
            debugging($message, $level = DEBUG_DEVELOPER);
×
676
            return false;
×
677
        }
678

679
        // Check role.
680
        if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
681
            debugging($this->get_name().': roleid #'.$roleid.' is not available.', $level = DEBUG_DEVELOPER);
×
682
            return false;
×
683
        }
684

685
        return true;
×
686
    }
687

688
    /**
689
     * Détermine si un utilisateur peut se réinscrire.
690
     *
691
     * @param object          $instance Objet de l'instance de la méthode d'inscription.
692
     * @param null|int|string $userid   Identifiant d'un utilisateur.
693
     * @param null|int|string $roleid   Identifiant d'un rôle.
694
     *
695
     * @return bool Vrai si les inscriptions sont ouvertes.
696
     */
697
    public function can_reenrol($instance, $userid = null, $roleid = null) {
698
        global $DB, $USER;
699

700
        $today = time();
×
701

702
        if ($userid === null) {
×
703
            $userid = $USER->id;
×
704
        }
705

706
        // Check reenrol enabled.
707
        if (empty($instance->customint6)) {
×
708
            debugging($this->get_name().' reenrol not enabled.', $level = DEBUG_DEVELOPER);
×
709
            return false;
×
710
        }
711

712
        // Check reenrol exists.
713
        $enrol = $DB->get_record('enrol', ['id' => $instance->customint6, 'enrol' => 'select']);
×
714
        if ($enrol === false) {
×
715
            debugging($this->get_name().' reenrol id #'.$instance->customint6.' does not exist', $level = DEBUG_DEVELOPER);
×
716
            return false;
×
717
        }
718

719
        // Check opening reenrol period.
720
        if ($instance->customint4 !== '0' && $instance->customint4 > $today) {
×
721
            debugging($this->get_name().' not opened yet.', $level = DEBUG_DEVELOPER);
×
722
            return false;
×
723
        }
724

725
        // Check closing reenrol period.
726
        if ($instance->customint5 !== '0' && $instance->customint5 < $today) {
×
727
            debugging($this->get_name().' already closed.', $level = DEBUG_DEVELOPER);
×
728
            return false;
×
729
        }
730

731
        // Check cohorts.
732
        if ($instance->customint3 === '1') {
×
733
            $usercohorts = $DB->get_records('cohort_members', ['userid' => $userid]);
×
734
            $enrolcohorts = $DB->get_records('enrol_select_cohorts', ['enrolid' => $instance->id], '', 'cohortid');
×
735

736
            $found = false;
×
737
            foreach ($usercohorts as $cohort) {
×
738
                if (isset($enrolcohorts[$cohort->cohortid])) {
×
739
                    $found = true;
×
740
                    break;
×
741
                }
742
            }
743

744
            if ($found !== true) {
×
745
                debugging($this->get_name().': userid #'.$userid.' and enrol cohort mismatch.', $level = DEBUG_DEVELOPER);
×
746
                return false;
×
747
            }
748
        }
749

750
        // We don't check available slots.
751
        // We don't check user limit.
752

753
        // Check role.
754
        if ($roleid !== null) {
×
755
            if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
756
                debugging($this->get_name().': roleid #'.$roleid.' is not available.', $level = DEBUG_DEVELOPER);
×
757
                return false;
×
758
            }
759
        }
760

761
        return true;
×
762
    }
763

764
    /**
765
     * Méthode permettant l'inscription d'un utilisateur à une instance.
766
     *
767
     * @param stdClass        $instance      Objet de l'instance de la méthode d'inscription.
768
     * @param int|string      $userid        Identifiant d'un utilisateur.
769
     * @param null|int|string $roleid        Identifiant d'un rôle.
770
     * @param int|string      $timestart     Timestamp de début de cours.
771
     * @param int|string      $timeend       Timestamp de fin de cours.
772
     * @param null|int|string $status        État de l'inscription (accepté, liste principale, liste secondaire, supprimé).
773
     * @param null|bool       $recovergrades Récupérer les notes ?
774
     *
775
     * @return void.
776
     */
777
    public function enrol_user(stdClass $instance, $userid, $roleid = null, $timestart = 0, $timeend = 0,
778
        $status = null, $recovergrades = null) {
779
        global $DB, $USER;
780

781
        // La méthode parent::enrol_user() ne remplace pas les rôles, mais cumul.
782
        // Il faut donc faire un traitement différent si il s'agit juste d'un changement de rôle.
783
        $enrolled = $DB->get_record('user_enrolments', ['enrolid' => $instance->id, 'userid' => $userid]);
3✔
784
        if ($enrolled === false) {
3✔
785
            if ($timestart === 0) {
3✔
786
                $timestart = $instance->customint7;
3✔
787
            }
788

789
            if ($timeend === 0) {
3✔
790
                $timeend = $instance->customint8;
3✔
791
            }
792

793
            parent::enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status, $recovergrades);
3✔
794

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

800
                $task = new enrol_select\task\check_enrolment_payment();
×
801
                $task->set_next_run_time(time() + $instance->customdec1);
×
802
                $task->set_custom_data($customdata);
×
803
                $task->set_userid($userid);
×
804

805
                core\task\manager::queue_adhoc_task($task);
×
806
            }
807

808
            // Notifie le nouvel inscrit.
809
            if ($userid === $USER->id) {
3✔
810
                $message = '';
3✔
811
                switch ($status) {
812
                    case self::ACCEPTED:
813
                        $message = $instance->customtext1;
3✔
814
                        break;
3✔
815
                    case self::MAIN:
3✔
816
                        $message = $instance->customtext2;
3✔
817
                        break;
3✔
818
                    case self::WAIT:
3✔
819
                        $message = $instance->customtext3;
3✔
820
                        break;
3✔
821
                }
822

823
                if (empty($message) === false) {
3✔
824
                    $course = $DB->get_record('course', ['id' => $instance->courseid]);
3✔
825

826
                    $eventdata = new \core\message\message();
3✔
827
                    $eventdata->name = 'select_notification';
3✔
828
                    $eventdata->component = 'enrol_select';
3✔
829
                    $eventdata->userfrom = get_admin();
3✔
830
                    $eventdata->userto = $userid;
3✔
831
                    $params = format_string($course->fullname, $striplinks = true, $course->id);
3✔
832
                    $eventdata->subject = get_string('enrolment_to', 'enrol_select', $params);
3✔
833
                    $eventdata->fullmessage = $message;
3✔
834
                    $eventdata->fullmessageformat = FORMAT_HTML;
3✔
835
                    $eventdata->fullmessagehtml = $message;
3✔
836
                    $eventdata->smallmessage = '';
3✔
837
                    $eventdata->notification = 1;
3✔
838
                    $eventdata->courseid = $course->id;
3✔
839

840
                    message_send($eventdata);
3✔
841
                }
842
            }
843

844
            return;
3✔
845
        }
846

847
        // Traite le cas où on souhaite juste modifier le statut.
848
        if ($status !== null) {
3✔
849
            $sql = "UPDATE {user_enrolments}".
3✔
850
                " SET status = :status, timemodified = :now".
3✔
851
                " WHERE enrolid = :enrolid".
3✔
852
                " AND userid = :userid";
3✔
853
            $DB->execute($sql, ['status' => $status, 'now' => time(), 'enrolid' => $instance->id, 'userid' => $userid]);
3✔
854
        }
855

856
        // Traite le cas où on souhaite juste modifier le rôle.
857
        if ($roleid !== null) {
3✔
858
            $coursecontext = context_course::instance($instance->courseid);
3✔
859

860
            $sql = "UPDATE {role_assignments}".
3✔
861
                " SET roleid = :roleid, timemodified = :now".
3✔
862
                " WHERE component = 'enrol_select'".
3✔
863
                " AND userid = :userid".
3✔
864
                " AND contextid = :contextid".
3✔
865
                " AND itemid= :itemid";
3✔
866
            $params = [
3✔
867
                'roleid' => $roleid,
3✔
868
                'now' => time(),
3✔
869
                'userid' => $userid,
3✔
870
                'contextid' => $coursecontext->id,
3✔
871
                'itemid' => $instance->id,
3✔
872
            ];
3✔
873
            $DB->execute($sql, $params);
3✔
874
        }
875
    }
876

877
    /**
878
     * Méthode permettant de déinscrire un utilisateur d'une instance.
879
     *
880
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
881
     * @param int|string $userid        Identifiant d'un utilisateur.
882
     *
883
     * @return void.
884
     */
885
    public function unenrol_user(stdClass $instance, $userid) {
886
        global $DB;
887

888
        parent::unenrol_user($instance, $userid);
3✔
889

890
        // Si la remontée de liste est activée.
891
        if (empty($instance->customchar2) === false) {
3✔
892
            $this->refill_main_list($instance, $userid);
3✔
893
        }
894

895
        // Si les paiements à l'inscription sont activées.
896
        $instance->customdec1 = intval($instance->customdec1);
3✔
897
        if (empty($instance->customdec1) === false) {
3✔
898
            // On supprime la tâche adhoc associée à l'utilisateur.
899
            $classname = '\enrol_select\task\check_enrolment_payment';
×
900
            $params = ['component' => 'enrol_select', 'classname' => $classname, 'userid' => $userid];
×
901
            $tasks = $DB->get_records('task_adhoc', $params);
×
902
            foreach ($tasks as $taskid => $task) {
×
903
                $customdata = json_decode($task->customdata);
×
904
                if (isset($customdata->enrolid) === false) {
×
905
                    continue;
×
906
                }
907

908
                if ($customdata->enrolid !== $instance->id) {
×
909
                    continue;
×
910
                }
911

912
                $DB->delete_records('task_adhoc', ['id' => $taskid]);
×
913
            }
914
        }
915
    }
916

917
    /**
918
     * Réorganise la liste d'inscription principale.
919
     *
920
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
921
     * @param int|string $userid        Identifiant d'un utilisateur.
922
     *
923
     * @return void.
924
     */
925
    public function refill_main_list(stdClass $instance, $userid) {
926
        global $DB, $USER;
927

928
        if ($this->is_enrol_period_active($instance) === false) {
3✔
929
            // On ne réalimente pas la liste principale si les inscriptions sont closes.
930
            return;
3✔
931
        }
932

933
        if ($USER->id !== $userid) {
3✔
934
            // L'utilisateur courant n'est pas l'utilisateur à désinscrire.
935
            // Il s'agit probablement d'un enseignant dans la partie management.
936
            // On ne provoque pas la réalimentation de la liste principale.
937
            return;
3✔
938
        }
939

940
        if (empty($instance->customint3) === true) {
3✔
941
            // Les quotas ne sont pas activés pour ce cours.
942
            return;
3✔
943
        }
944

945
        $sql = "SELECT COUNT(*) FROM {user_enrolments} WHERE enrolid = :enrolid AND status IN (:main, :accepted)";
3✔
946
        $params = ['enrolid' => $instance->id, 'main' => self::MAIN, 'accepted' => self::ACCEPTED];
3✔
947
        $countmain = $DB->count_records_sql($sql, $params);
3✔
948
        if ($countmain >= $instance->customint1) {
3✔
949
            // La liste principale (et des acceptés) est déjà pleine.
950
            return;
3✔
951
        }
952

953
        $countwait = $DB->count_records('user_enrolments', ['enrolid' => $instance->id, 'status' => self::WAIT]);
3✔
954
        if ($countwait === 0) {
3✔
955
            // La liste complémentaire est vide.
956
            return;
3✔
957
        }
958

959
        // Détermine le nombre d'inscription à transférer de la liste complémentaire à la liste principale.
960
        $promote = $instance->customint1 - $countmain;
3✔
961

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

966
        $course = $DB->get_record('course', ['id' => $instance->courseid], '*', MUST_EXIST);
3✔
967
        foreach ($waitingusers as $user) {
3✔
968
            $user->status = self::MAIN;
3✔
969
            $DB->update_record('user_enrolments', $user);
3✔
970

971
            // Notifie l'utilisateur sur liste d'attente qui vient d'être basculé sur liste principale.
972
            $eventdata = new \core\message\message();
3✔
973
            $eventdata->courseid = $course->id;
3✔
974
            $eventdata->component = 'enrol_select';
3✔
975
            $eventdata->name = 'select_notification';
3✔
976
            $eventdata->userfrom = core_user::get_noreply_user();
3✔
977
            $eventdata->userto = $DB->get_record('user', ['id' => $user->userid]);
3✔
978
            $eventdata->subject = get_string('enrolcoursesubject', 'enrol_select', $course);
3✔
979
            $eventdata->fullmessage = get_string('message_promote', 'enrol_select');
3✔
980
            $eventdata->fullmessageformat = FORMAT_PLAIN;
3✔
981
            $eventdata->fullmessagehtml = '';
3✔
982
            $eventdata->smallmessage = '';
3✔
983
            $eventdata->notification = 1;
3✔
984

985
            message_send($eventdata);
3✔
986

987
            $promote--;
3✔
988
            if ($promote === 0) {
3✔
989
                break;
3✔
990
            }
991
        }
992
    }
993
}
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