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

apsolu / enrol_select / 14660736547

25 Apr 2025 08:42AM UTC coverage: 14.159% (-0.1%) from 14.286%
14660736547

push

github

jboulen
test(behat): désactive la remontée des messages de debug relatifs aux inscriptions lors d'exécution de tests Behat

0 of 26 new or added lines in 2 files covered. (0.0%)

1 existing line in 1 file now uncovered.

144 of 1017 relevant lines covered (14.16%)

1.13 hits per line

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

33.16
/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) {
8✔
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);
8✔
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]);
8✔
355
        if ($userenrolment !== false) {
8✔
356
            // Retourne la liste d'inscription actuelle de l'utilisateur.
357
            return $userenrolment->status;
8✔
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];
8✔
362
        $waitlistenrolements = $DB->get_records('user_enrolments', $params, '', 'userid');
8✔
363
        $this->count_wait_list_enrolements = count($waitlistenrolements);
8✔
364

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

372
        if ($countwaitlistenrolements >= $instance->customint2 && empty($instance->customint2) === false) {
8✔
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;
8✔
376
        }
377

378
        if ($countwaitlistenrolements !== 0) {
8✔
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;
8✔
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".
8✔
385
            " FROM {user_enrolments}".
8✔
386
            " WHERE enrolid = :enrolid".
8✔
387
            " AND status IN (:accepted, :main)";
8✔
388
        $params = ['enrolid' => $instance->id, 'accepted' => self::ACCEPTED, 'main' => self::MAIN];
8✔
389
        $mainlistenrolements = $DB->get_records_sql($sql, $params);
8✔
390
        $this->count_main_list_enrolements = count($mainlistenrolements);
8✔
391

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

399
        if ($countmainlistenrolements < $instance->customint1 && empty($instance->customint1) === false) {
8✔
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);
8✔
402
        }
403

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

410
        // Il n'y a pas de liste complémentaire. Il n'est plus possible de s'inscrire.
411
        return false;
8✔
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) {
8✔
423
            return self::ACCEPTED;
8✔
424
        }
425

426
        return self::MAIN;
8✔
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

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
517
              ORDER BY r.sortorder";
×
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

NEW
608
        $loglevel = DEBUG_DEVELOPER;
×
NEW
609
        if (defined('BEHAT_SITE_RUNNING') === true) {
×
NEW
610
            $loglevel = DEBUG_NONE;
×
611
        }
612

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

619
        // Check closing register period.
620
        if ($instance->enrolenddate !== '0' && $instance->enrolenddate < $today) {
×
NEW
621
            debugging($this->get_name().' already closed.', $loglevel);
×
622
            return false;
×
623
        }
624

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

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

637
        if ($found !== true) {
×
NEW
638
            debugging($this->get_name().': '.$user->username.' and enrol cohort mismatch.', $loglevel);
×
639
            return false;
×
640
        }
641

642
        $federationcourse = new FederationCourse();
×
643
        if ($instance->courseid === $federationcourse->get_courseid()) {
×
644
            // Bidouille moche pour gérer l'inscription à la FFSU.
645
            return true;
×
646
        }
647

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

656
        // Check available slots.
657
        if ($this->get_available_status($instance, $user) === false) {
×
NEW
658
            debugging($this->get_name().' n\'a plus aucune place disponible.', $loglevel);
×
659
            return false;
×
660
        }
661

662
        // Check user limit.
663
        $userchoices = enrol_select_get_sum_user_choices($userid = null, $count = true);
×
664
        $available = false;
×
665
        foreach ($userchoices as $choice) {
×
666
            if ($choice->roleid != $roleid) {
×
667
                continue;
×
668
            }
669

670
            if ($choice->maxwish == 0 || $choice->count < $choice->maxwish) {
×
671
                $available = true;
×
672
                break;
×
673
            }
674
        }
675

676
        if ($available === false) {
×
677
            $parameters = ['userid' => $user->id, 'roleid' => $roleid];
×
678
            $message = get_string('the_user_X_has_reached_their_wish_limit_for_the_role_Y', 'enrol_select', $parameters);
×
679

NEW
680
            debugging($message, $loglevel);
×
681
            return false;
×
682
        }
683

684
        // Check role.
685
        if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
NEW
686
            debugging($this->get_name().': roleid #'.$roleid.' is not available.', $loglevel);
×
687
            return false;
×
688
        }
689

690
        return true;
×
691
    }
692

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

705
        $today = time();
×
706

NEW
707
        $loglevel = DEBUG_DEVELOPER;
×
NEW
708
        if (defined('BEHAT_SITE_RUNNING') === true) {
×
NEW
709
            $loglevel = DEBUG_NONE;
×
710
        }
711

712
        if ($userid === null) {
×
713
            $userid = $USER->id;
×
714
        }
715

716
        // Check reenrol enabled.
717
        if (empty($instance->customint6)) {
×
NEW
718
            debugging($this->get_name().' reenrol not enabled.', $loglevel);
×
719
            return false;
×
720
        }
721

722
        // Check reenrol exists.
723
        $enrol = $DB->get_record('enrol', ['id' => $instance->customint6, 'enrol' => 'select']);
×
724
        if ($enrol === false) {
×
NEW
725
            debugging($this->get_name().' reenrol id #'.$instance->customint6.' does not exist', $loglevel);
×
726
            return false;
×
727
        }
728

729
        // Check opening reenrol period.
730
        if ($instance->customint4 !== '0' && $instance->customint4 > $today) {
×
NEW
731
            debugging($this->get_name().' not opened yet.', $loglevel);
×
732
            return false;
×
733
        }
734

735
        // Check closing reenrol period.
736
        if ($instance->customint5 !== '0' && $instance->customint5 < $today) {
×
NEW
737
            debugging($this->get_name().' already closed.', $loglevel);
×
738
            return false;
×
739
        }
740

741
        // Check cohorts.
742
        if ($instance->customint3 === '1') {
×
743
            $usercohorts = $DB->get_records('cohort_members', ['userid' => $userid]);
×
744
            $enrolcohorts = $DB->get_records('enrol_select_cohorts', ['enrolid' => $instance->id], '', 'cohortid');
×
745

746
            $found = false;
×
747
            foreach ($usercohorts as $cohort) {
×
748
                if (isset($enrolcohorts[$cohort->cohortid])) {
×
749
                    $found = true;
×
750
                    break;
×
751
                }
752
            }
753

754
            if ($found !== true) {
×
NEW
755
                debugging($this->get_name().': userid #'.$userid.' and enrol cohort mismatch.', $loglevel);
×
756
                return false;
×
757
            }
758
        }
759

760
        // We don't check available slots.
761
        // We don't check user limit.
762

763
        // Check role.
764
        if ($roleid !== null) {
×
765
            if ($DB->get_record('enrol_select_roles', ['enrolid' => $instance->id, 'roleid' => $roleid]) === false) {
×
NEW
766
                debugging($this->get_name().': roleid #'.$roleid.' is not available.', $loglevel);
×
767
                return false;
×
768
            }
769
        }
770

771
        return true;
×
772
    }
773

774
    /**
775
     * Méthode permettant l'inscription d'un utilisateur à une instance.
776
     *
777
     * @param stdClass        $instance      Objet de l'instance de la méthode d'inscription.
778
     * @param int|string      $userid        Identifiant d'un utilisateur.
779
     * @param null|int|string $roleid        Identifiant d'un rôle.
780
     * @param int|string      $timestart     Timestamp de début de cours.
781
     * @param int|string      $timeend       Timestamp de fin de cours.
782
     * @param null|int|string $status        État de l'inscription (accepté, liste principale, liste secondaire, supprimé).
783
     * @param null|bool       $recovergrades Récupérer les notes ?
784
     *
785
     * @return void.
786
     */
787
    public function enrol_user(stdClass $instance, $userid, $roleid = null, $timestart = 0, $timeend = 0,
788
        $status = null, $recovergrades = null) {
789
        global $DB, $USER;
790

791
        // La méthode parent::enrol_user() ne remplace pas les rôles, mais cumul.
792
        // Il faut donc faire un traitement différent si il s'agit juste d'un changement de rôle.
793
        $enrolled = $DB->get_record('user_enrolments', ['enrolid' => $instance->id, 'userid' => $userid]);
8✔
794
        if ($enrolled === false) {
8✔
795
            if ($timestart === 0) {
8✔
796
                $timestart = $instance->customint7;
8✔
797
            }
798

799
            if ($timeend === 0) {
8✔
800
                $timeend = $instance->customint8;
8✔
801
            }
802

803
            parent::enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status, $recovergrades);
8✔
804

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

810
                $task = new enrol_select\task\check_enrolment_payment();
×
811
                $task->set_next_run_time(time() + $instance->customdec1);
×
812
                $task->set_custom_data($customdata);
×
813
                $task->set_userid($userid);
×
814

815
                core\task\manager::queue_adhoc_task($task);
×
816
            }
817

818
            // Notifie le nouvel inscrit.
819
            if ($userid === $USER->id) {
8✔
820
                $message = '';
8✔
821
                switch ($status) {
822
                    case self::ACCEPTED:
823
                        $message = $instance->customtext1;
8✔
824
                        break;
8✔
825
                    case self::MAIN:
8✔
826
                        $message = $instance->customtext2;
8✔
827
                        break;
8✔
828
                    case self::WAIT:
8✔
829
                        $message = $instance->customtext3;
8✔
830
                        break;
8✔
831
                }
832

833
                if (empty($message) === false) {
8✔
834
                    $course = $DB->get_record('course', ['id' => $instance->courseid]);
8✔
835

836
                    $eventdata = new \core\message\message();
8✔
837
                    $eventdata->name = 'select_notification';
8✔
838
                    $eventdata->component = 'enrol_select';
8✔
839
                    $eventdata->userfrom = get_admin();
8✔
840
                    $eventdata->userto = $userid;
8✔
841
                    $params = format_string($course->fullname, $striplinks = true, $course->id);
8✔
842
                    $eventdata->subject = get_string('enrolment_to', 'enrol_select', $params);
8✔
843
                    $eventdata->fullmessage = $message;
8✔
844
                    $eventdata->fullmessageformat = FORMAT_HTML;
8✔
845
                    $eventdata->fullmessagehtml = $message;
8✔
846
                    $eventdata->smallmessage = '';
8✔
847
                    $eventdata->notification = 1;
8✔
848
                    $eventdata->courseid = $course->id;
8✔
849

850
                    message_send($eventdata);
8✔
851
                }
852
            }
853

854
            return;
8✔
855
        }
856

857
        // Traite le cas où on souhaite juste modifier le statut.
858
        if ($status !== null) {
8✔
859
            $sql = "UPDATE {user_enrolments}".
8✔
860
                " SET status = :status, timemodified = :now".
8✔
861
                " WHERE enrolid = :enrolid".
8✔
862
                " AND userid = :userid";
8✔
863
            $DB->execute($sql, ['status' => $status, 'now' => time(), 'enrolid' => $instance->id, 'userid' => $userid]);
8✔
864
        }
865

866
        // Traite le cas où on souhaite juste modifier le rôle.
867
        if ($roleid !== null) {
8✔
868
            $coursecontext = context_course::instance($instance->courseid);
8✔
869

870
            $sql = "UPDATE {role_assignments}".
8✔
871
                " SET roleid = :roleid, timemodified = :now".
8✔
872
                " WHERE component = 'enrol_select'".
8✔
873
                " AND userid = :userid".
8✔
874
                " AND contextid = :contextid".
8✔
875
                " AND itemid= :itemid";
8✔
876
            $params = [
8✔
877
                'roleid' => $roleid,
8✔
878
                'now' => time(),
8✔
879
                'userid' => $userid,
8✔
880
                'contextid' => $coursecontext->id,
8✔
881
                'itemid' => $instance->id,
8✔
882
            ];
8✔
883
            $DB->execute($sql, $params);
8✔
884
        }
885
    }
886

887
    /**
888
     * Méthode permettant de déinscrire un utilisateur d'une instance.
889
     *
890
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
891
     * @param int|string $userid        Identifiant d'un utilisateur.
892
     *
893
     * @return void.
894
     */
895
    public function unenrol_user(stdClass $instance, $userid) {
896
        global $DB;
897

898
        parent::unenrol_user($instance, $userid);
8✔
899

900
        // Si la remontée de liste est activée.
901
        if (empty($instance->customchar2) === false) {
8✔
902
            $this->refill_main_list($instance, $userid);
8✔
903
        }
904

905
        // Si les paiements à l'inscription sont activées.
906
        $instance->customdec1 = intval($instance->customdec1);
8✔
907
        if (empty($instance->customdec1) === false) {
8✔
908
            // On supprime la tâche adhoc associée à l'utilisateur.
909
            $classname = '\enrol_select\task\check_enrolment_payment';
×
910
            $params = ['component' => 'enrol_select', 'classname' => $classname, 'userid' => $userid];
×
911
            $tasks = $DB->get_records('task_adhoc', $params);
×
912
            foreach ($tasks as $taskid => $task) {
×
913
                $customdata = json_decode($task->customdata);
×
914
                if (isset($customdata->enrolid) === false) {
×
915
                    continue;
×
916
                }
917

918
                if ($customdata->enrolid !== $instance->id) {
×
919
                    continue;
×
920
                }
921

922
                $DB->delete_records('task_adhoc', ['id' => $taskid]);
×
923
            }
924
        }
925
    }
926

927
    /**
928
     * Réorganise la liste d'inscription principale.
929
     *
930
     * @param stdClass   $instance      Objet de l'instance de la méthode d'inscription.
931
     * @param int|string $userid        Identifiant d'un utilisateur.
932
     *
933
     * @return void.
934
     */
935
    public function refill_main_list(stdClass $instance, $userid) {
936
        global $DB, $USER;
937

938
        if ($this->is_enrol_period_active($instance) === false) {
8✔
939
            // On ne réalimente pas la liste principale si les inscriptions sont closes.
940
            return;
8✔
941
        }
942

943
        if ($USER->id !== $userid) {
8✔
944
            // L'utilisateur courant n'est pas l'utilisateur à désinscrire.
945
            // Il s'agit probablement d'un enseignant dans la partie management.
946
            // On ne provoque pas la réalimentation de la liste principale.
947
            return;
8✔
948
        }
949

950
        if (empty($instance->customint3) === true) {
8✔
951
            // Les quotas ne sont pas activés pour ce cours.
952
            return;
8✔
953
        }
954

955
        $sql = "SELECT COUNT(*) FROM {user_enrolments} WHERE enrolid = :enrolid AND status IN (:main, :accepted)";
8✔
956
        $params = ['enrolid' => $instance->id, 'main' => self::MAIN, 'accepted' => self::ACCEPTED];
8✔
957
        $countmain = $DB->count_records_sql($sql, $params);
8✔
958
        if ($countmain >= $instance->customint1) {
8✔
959
            // La liste principale (et des acceptés) est déjà pleine.
960
            return;
8✔
961
        }
962

963
        $countwait = $DB->count_records('user_enrolments', ['enrolid' => $instance->id, 'status' => self::WAIT]);
8✔
964
        if ($countwait === 0) {
8✔
965
            // La liste complémentaire est vide.
966
            return;
8✔
967
        }
968

969
        // Détermine le nombre d'inscription à transférer de la liste complémentaire à la liste principale.
970
        $promote = $instance->customint1 - $countmain;
8✔
971

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

976
        $course = $DB->get_record('course', ['id' => $instance->courseid], '*', MUST_EXIST);
8✔
977
        foreach ($waitingusers as $user) {
8✔
978
            $user->status = self::MAIN;
8✔
979
            $DB->update_record('user_enrolments', $user);
8✔
980

981
            // Notifie l'utilisateur sur liste d'attente qui vient d'être basculé sur liste principale.
982
            $eventdata = new \core\message\message();
8✔
983
            $eventdata->courseid = $course->id;
8✔
984
            $eventdata->component = 'enrol_select';
8✔
985
            $eventdata->name = 'select_notification';
8✔
986
            $eventdata->userfrom = core_user::get_noreply_user();
8✔
987
            $eventdata->userto = $DB->get_record('user', ['id' => $user->userid]);
8✔
988
            $eventdata->subject = get_string('enrolcoursesubject', 'enrol_select', $course);
8✔
989
            $eventdata->fullmessage = get_string('message_promote', 'enrol_select');
8✔
990
            $eventdata->fullmessageformat = FORMAT_PLAIN;
8✔
991
            $eventdata->fullmessagehtml = '';
8✔
992
            $eventdata->smallmessage = '';
8✔
993
            $eventdata->notification = 1;
8✔
994

995
            message_send($eventdata);
8✔
996

997
            $promote--;
8✔
998
            if ($promote === 0) {
8✔
999
                break;
8✔
1000
            }
1001
        }
1002
    }
1003
}
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