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

apsolu / local_apsolu / 19769187391

28 Nov 2025 03:37PM UTC coverage: 10.807% (-0.7%) from 11.491%
19769187391

push

github

jboulen
fix(attendance): corrige un bug qui empêchait la prise de présences par QR code aux invités

679 of 6283 relevant lines covered (10.81%)

0.35 hits per line

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

50.0
/classes/core/course.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
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
18
// phpcs:disable moodle.NamingConventions.ValidVariableName.MemberNameUnderscore
19

20
namespace local_apsolu\core;
21

22
use coding_exception;
23
use context_block;
24
use context_course;
25
use core_course_category;
26
use core_php_time_limit;
27
use grade_category;
28
use grade_item;
29
use moodle_exception;
30
use moodle_url;
31
use stdClass;
32

33
/**
34
 * Classe gérant les créneaux horaires APSOLU (cours Moodle).
35
 *
36
 * @package    local_apsolu
37
 * @copyright  2019 Université Rennes 2 <dsi-contact@univ-rennes2.fr>
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class course extends record {
41
    /**
42
     * Nom de la table de référence en base de données.
43
     */
44
    const TABLENAME = 'apsolu_courses';
45

46
    /** @var int|string Identifiant numérique du créneau horaire. */
47
    public $id = 0;
48

49
    /** @var string $shortname Nom abrégé du créneau horaire. */
50
    public $shortname = '';
51

52
    /** @var string $fullname Nom complet du créneau horaire. */
53
    public $fullname = '';
54

55
    /** @var string $idnumber Identifiant du créneau horaire. */
56
    public $idnumber = '';
57

58
    /** @var int|string $category Entier représentant l'identifiant de l'activité sportive. */
59
    public $category = '';
60

61
    /** @var string $event Précision sur la discipline ou la spécificité de
62
                           ce créneau (ex: 100m, 110m haies, football en salle, etc). */
63
    public $event = '';
64

65
    /** @var int|string $numweekday Ordre du jour (ex: 1 = lundi, 2 = mardi, etc). Facilite le tri dans la requête SQL. */
66
    public $numweekday = '';
67

68
    /** @var string $weekday Jour de la semaine en anglais. Champ à utiliser avec
69
                             la fonction Moodle get_string($weekday, 'local_apsolu'). */
70
    public $weekday = '';
71

72
    /** @var string $starttime Heure de début du créneau au format HH:MM. */
73
    public $starttime = '';
74

75
    /** @var string $endtime Heure de fin du créneau au format HH:MM. */
76
    public $endtime = '';
77

78
    /** @var bool $license Indique si le créneau nécessite l'adhésion à la FFSU. */
79
    public $license = 0;
80

81
    /** @var bool $on_homepage Indique si le créneau doit être affiché sur la homepage. */
82
    public $on_homepage = '';
83

84
    /** @var bool $showpolicy Indique si les recommandations médicales doivent être acceptées lors de l'inscription. */
85
    public $showpolicy = '';
86

87
    /** @var int|string $locationid Identifiant numérique du lieu de pratique. */
88
    public $locationid = '';
89

90
    /** @var int|string $periodid Identifiant numérique de la période de cours. */
91
    public $periodid = '';
92

93
    /** @var int|string $skillid Identifiant numérique du niveau de pratique. */
94
    public $skillid = '';
95

96
    /** @var string $information Informations additionnelles affichées après l'inscription à un créneau. */
97
    public $information = '';
98

99
    /** @var int|string $informationformat Identifiant numérique du format du texte. */
100
    public $informationformat = FORMAT_HTML;
101

102
    /** @var string $information_editor Variable pour le formulaire contenant l'éditeur de texte. */
103
    public $information_editor = '';
104

105
    /**
106
     * Affiche une représentation textuelle de l'objet.
107
     *
108
     * @return string.
109
     */
110
    public function __toString() {
111
        return $this->fullname;
×
112
    }
113

114
    /**
115
     * Supprime un objet en base de données.
116
     *
117
     * @throws moodle_exception A moodle exception is thrown when moodle course cannot be delete.
118
     * @throws dml_exception A DML specific exception is thrown for any errors.
119
     *
120
     * @return bool true.
121
     */
122
    public function delete() {
123
        global $DB;
124

125
        // Démarre une transaction, si ce n'est pas déjà fait.
126
        if ($DB->is_transaction_started() === false) {
2✔
127
            $transaction = $DB->start_delegated_transaction();
2✔
128
        }
129

130
        // This might take a while. Raise the execution time limit.
131
        core_php_time_limit::raise();
2✔
132

133
        // Supprime les sessions du cours.
134
        foreach ($this->get_sessions() as $session) {
2✔
135
            $session->delete();
×
136
        }
137

138
        // We do this here because it spits out feedback as it goes.
139
        $course = $DB->get_record('course', ['id' => $this->id], $fields = '*', MUST_EXIST);
2✔
140
        $result = delete_course($course, $showfeedback = false);
2✔
141

142
        if ($result === false) {
2✔
143
            $link = new moodle_url('/local/apsolu/courses/index.php', ['tab' => 'courses']);
×
144

145
            throw new moodle_exception('cannotdeletecategorycourse', $module = '', $link, $parameter = $this->fullname);
×
146
        }
147

148
        // Supprime l'objet en base de données.
149
        $DB->delete_records(self::TABLENAME, ['id' => $this->id]);
2✔
150

151
        // TODO: supprimer les notes.
152

153
        // Update course count in categories.
154
        fix_course_sortorder();
2✔
155

156
        // Valide la transaction en cours.
157
        if (isset($transaction) === true) {
2✔
158
            $transaction->allow_commit();
×
159
        }
160

161
        return true;
2✔
162
    }
163

164
    /**
165
     * Retourne l'id du cours de FFSU.
166
     *
167
     * @return int|false Retourne l'id du cours de FFSU ou false si il n'est pas défini.
168
     */
169
    public static function get_federation_courseid() {
170
        debugging(
×
171
            'Use of ' . __METHOD__ . ' is deprecated. Use local_apsolu\core\federation\course::get_courseid().',
×
172
            DEBUG_DEVELOPER
×
173
        );
×
174

175
        $federationcourse = get_config('local_apsolu', 'federation_course');
×
176

177
        if (empty($federationcourse) === true) {
×
178
            return false;
×
179
        }
180

181
        return $federationcourse;
×
182
    }
183

184
    /**
185
     * Calcule le nom complet du cours à partir des paramètres passés à la méthode.
186
     *
187
     * @param int|string $category  Identifiant ou nom de la catégorie d'activité sportive.
188
     * @param string     $event     Libellé complémentaire / spécialité.
189
     * @param string     $weekday   Jour de la semaine en anglais.
190
     * @param string     $starttime Heure de début du cours.
191
     * @param string     $endtime   Heure de fin du cours.
192
     * @param int|string $skill     Identifiant ou libellé du niveau de pratique.
193
     *
194
     * @return string Nom abrégé unique.
195
     */
196
    public static function get_fullname($category, $event, $weekday, $starttime, $endtime, $skill) {
197
        global $DB;
198

199
        if (ctype_digit($category) === true) {
×
200
            // Récupère le nom de la catégorie en base de données, si c'est un identifiant qui a été entré en paramètre.
201
            $record = $DB->get_record('course_categories', ['id' => $category], $fields = '*', MUST_EXIST);
×
202
            $category = $record->name;
×
203
        }
204

205
        if (ctype_digit($skill) === true) {
×
206
            // Récupère le nom du niveau de pratique en base de données, si c'est un identifiant qui a été entré en paramètre.
207
            $record = $DB->get_record('apsolu_skills', ['id' => $skill], $fields = '*', MUST_EXIST);
×
208
            $skill = $record->name;
×
209
        }
210

211
        $strtime = get_string($weekday, 'local_apsolu') . ' ' . $starttime . ' ' . $endtime;
×
212

213
        if (empty($event) === false) {
×
214
            return sprintf('%s %s %s %s', $category, $event, $strtime, $skill);
×
215
        }
216

217
        return sprintf('%s %s %s', $category, $strtime, $skill);
×
218
    }
219

220
    /**
221
     * Vérifie le nom abrégé du cours.
222
     *
223
     * Si le nom abrégé passé en paramètre est déjà utilisé, un nouveau nom abrégé est généré.
224
     *
225
     * @param int|string $courseid  Identifiant du cours.
226
     * @param string     $shortname Nom abrégé du cours à contrôler.
227
     *
228
     * @return string Nom abrégé unique.
229
     */
230
    public static function get_shortname($courseid, $shortname) {
231
        global $DB;
232

233
        // Contrôle que le nom abrégé est bien unique.
234
        while (true) {
×
235
            $course = $DB->get_record('course', ['shortname' => $shortname]);
×
236
            if ($course === false) {
×
237
                break;
×
238
            }
239

240
            if ($courseid === $course->id) {
×
241
                break;
×
242
            }
243

244
            $shortname .= '.';
×
245
        }
246

247
        return $shortname;
×
248
    }
249

250
    /**
251
     * Retourne l'index du jour de la semaine donné en paramètre.
252
     * ex: monday=1, tuesday=2, etc.
253
     *
254
     * @throws coding_exception A coding exception is thrown when $data parameter is null.
255
     *
256
     * @param string $day Jour de la semaine en anglais ou dans la langue locale de Moodle.
257
     *
258
     * @return int Numéro du jour de la semaine.
259
     */
260
    public static function get_numweekdays($day) {
261
        switch ($day) {
262
            case 'monday':
×
263
                return 1;
×
264
            case 'tuesday':
×
265
                return 2;
×
266
            case 'wednesday':
×
267
                return 3;
×
268
            case 'thursday':
×
269
                return 4;
×
270
            case 'friday':
×
271
                return 5;
×
272
            case 'saturday':
×
273
                return 6;
×
274
            case 'sunday':
×
275
                return 7;
×
276
        }
277

278
        switch ($day) {
279
            case get_string('monday', 'local_apsolu'):
×
280
                return 1;
×
281
            case get_string('tuesday', 'local_apsolu'):
×
282
                return 2;
×
283
            case get_string('wednesday', 'local_apsolu'):
×
284
                return 3;
×
285
            case get_string('thursday', 'local_apsolu'):
×
286
                return 4;
×
287
            case get_string('friday', 'local_apsolu'):
×
288
                return 5;
×
289
            case get_string('saturday', 'local_apsolu'):
×
290
                return 6;
×
291
            case get_string('sunday', 'local_apsolu'):
×
292
                return 7;
×
293
        }
294

295
        throw new coding_exception('Invalid value (' . json_encode(['day' => $day]) . ' for ' . __METHOD__ . '.');
×
296
    }
297

298
    /**
299
     * Recherche et instancie des objets depuis la base de données.
300
     *
301
     * @see Se référer à la documentation de la méthode get_records() de la variable globale $DB.
302
     * @param array|null $conditions Critères de sélection des objets.
303
     * @param string     $sort       Champs par lesquels s'effectue le tri.
304
     * @param string     $fields     Liste des champs retournés.
305
     * @param int        $limitfrom  Retourne les enregistrements à partir de n+$limitfrom.
306
     * @param int        $limitnum   Nombre total d'enregistrements retournés.
307
     *
308
     * @return array Un tableau d'objets instanciés.
309
     */
310
    public static function get_records(
311
        ?array $conditions = null,
312
        string $sort = '',
313
        string $fields = '*',
314
        int $limitfrom = 0,
315
        int $limitnum = 0
316
    ) {
317
        global $DB;
318

319
        $classname = __CLASS__;
×
320

321
        $records = [];
×
322

323
        foreach ($DB->get_records(get_called_class()::TABLENAME, $conditions, $sort, $fields, $limitfrom, $limitnum) as $data) {
×
324
            $record = new $classname();
×
325
            $record->set_vars($data);
×
326
            $records[$record->id] = $record;
×
327
        }
328

329
        return $records;
×
330
    }
331

332
    /**
333
     * Retourne le nombre de secondes écoulées entre le début de la semaine et le début du cours.
334
     *
335
     * @throws coding_exception Lève une exception lorsque la date de début du cours est mal formatée.
336
     *
337
     * @return int
338
     */
339
    public function get_session_offset() {
340
        if (preg_match('/^[0-9][0-9]:[0-9][0-9]$/', $this->starttime) !== 1) {
2✔
341
            throw new coding_exception('Unexpected value of starttime (' . $this->starttime . ') for ' . __METHOD__ . '.');
2✔
342
        }
343

344
        [$hours, $minutes] = explode(':', $this->starttime);
2✔
345

346
        $offset = 0;
2✔
347
        $offset += (($this->numweekday - 1) * 24 * 60 * 60);
2✔
348
        $offset += ($hours * 60 * 60);
2✔
349
        $offset += ($minutes * 60);
2✔
350

351
        return $offset;
2✔
352
    }
353

354
    /**
355
     * Retourne les sessions du cours.
356
     *
357
     * @return array Retourne un tableau d'objets attendancesession.
358
     */
359
    public function get_sessions() {
360
        return attendancesession::get_records(['courseid' => $this->id]);
×
361
    }
362

363
    /**
364
     * Retourne un tableau trié par jour de la semaine et indéxé par le nom du jour en anglais.
365
     *
366
     * @return array Tableau trié et indéxé par le jour de la semaine en anglais.
367
     */
368
    public static function get_weekdays() {
369
        $weekdays = [];
×
370
        $weekdays['monday'] = get_string('monday', 'local_apsolu');
×
371
        $weekdays['tuesday'] = get_string('tuesday', 'local_apsolu');
×
372
        $weekdays['wednesday'] = get_string('wednesday', 'local_apsolu');
×
373
        $weekdays['thursday'] = get_string('thursday', 'local_apsolu');
×
374
        $weekdays['friday'] = get_string('friday', 'local_apsolu');
×
375
        $weekdays['saturday'] = get_string('saturday', 'local_apsolu');
×
376
        $weekdays['sunday'] = get_string('sunday', 'local_apsolu');
×
377

378
        return $weekdays;
×
379
    }
380

381
    /**
382
     * Retourne la durée d'un cours en secondes à partir de son heure de début et son heure de fin.
383
     *
384
     * @param string $starttime Date de début du cours au format hh:mm.
385
     * @param string $endtime   Date de fin du cours au format hh:mm.
386
     *
387
     * @return int|false Durée en secondes du cours, ou false si une erreur est détectée.
388
     */
389
    public static function getDuration(string $starttime, string $endtime) {
390
        $times = [];
×
391
        $times['starttime'] = explode(':', $starttime);
×
392
        $times['endtime'] = explode(':', $endtime);
×
393

394
        foreach ($times as $key => $values) {
×
395
            if (count($values) !== 2) {
×
396
                debugging(__METHOD__ . ': 2 valeurs attendues pour la variable $' . $key, $level = DEBUG_DEVELOPER);
×
397

398
                return false;
×
399
            }
400

401
            if (ctype_digit($values[0]) === false || ctype_digit($values[1]) === false) {
×
402
                debugging(__METHOD__ . ': 2 entiers attendus pour la variable $' . $key, $level = DEBUG_DEVELOPER);
×
403

404
                return false;
×
405
            }
406

407
            $times[$key] = $values[0] * 60 * 60 + $values[1] * 60;
×
408
        }
409

410
        $duration = $times['endtime'] - $times['starttime'];
×
411

412
        if ($duration <= 0) {
×
413
            debugging(__METHOD__ . ': valeur nulle ou négative pour la variable $duration', $level = DEBUG_DEVELOPER);
×
414

415
            return false;
×
416
        }
417

418
        return $duration;
×
419
    }
420

421
    /**
422
     * Charge un objet à partir de son identifiant.
423
     *
424
     * @param int|string $recordid Identifiant de l'objet à charger.
425
     * @param bool       $required Si true, lève une exception lorsque l'objet n'existe pas.
426
                                   Valeur par défaut: false (pas d'exception levée).
427
     *
428
     * @return void
429
     */
430
    public function load($recordid, bool $required = false) {
431
        global $DB;
432

433
        $strictness = IGNORE_MISSING;
2✔
434
        if ($required) {
2✔
435
            $strictness = MUST_EXIST;
×
436
        }
437

438
        $sql = "SELECT c.id, c.shortname, c.fullname, c.category, ac.event, ac.skillid, ac.locationid,
2✔
439
                       ac.numweekday, ac.weekday, ac.starttime, ac.endtime, ac.periodid,
440
                       ac.license, ac.on_homepage, ac.showpolicy, ac.information, ac.informationformat
441
                  FROM {course} c
442
                  JOIN {apsolu_courses} ac ON ac.id=c.id
443
                 WHERE c.id = :id";
2✔
444
        $record = $DB->get_record_sql($sql, ['id' => $recordid], $strictness);
2✔
445

446
        if ($record === false) {
2✔
447
            return;
2✔
448
        }
449

450
        $this->set_vars($record);
2✔
451
    }
452

453
    /**
454
     * Enregistre un objet en base de données.
455
     *
456
     * @throws coding_exception A coding exception is thrown when $data parameter is null.
457
     * @throws dml_exception A DML specific exception is thrown for any errors.
458
     *
459
     * @param object|null $data  StdClass représentant l'objet à enregistrer.
460
     * @param object|null $mform Mform représentant un formulaire Moodle nécessaire à la gestion d'un champ de type editor.
461
     *
462
     * @return void
463
     */
464
    public function save(?object $data = null, ?object $mform = null) {
465
        global $DB;
466

467
        if ($data === null) {
2✔
468
            throw new coding_exception('$data parameter cannot be null for ' . __METHOD__ . '.');
×
469
        }
470

471
        $this->set_vars($data);
2✔
472
        $this->numweekday = self::get_numweekdays($this->weekday);
2✔
473

474
        // Set fullname.
475
        $this->fullname = self::get_fullname(
2✔
476
            $data->str_category,
2✔
477
            $this->event,
2✔
478
            $this->weekday,
2✔
479
            $this->starttime,
2✔
480
            $this->endtime,
2✔
481
            $data->str_skill
2✔
482
        );
2✔
483

484
        // Set shortname.
485
        $this->shortname = self::get_shortname($this->id, $this->fullname);
2✔
486

487
        if (isset($data->idnumber) === true) {
2✔
488
            $this->idnumber = $data->idnumber;
2✔
489
        }
490

491
        // TODO: controler que endtime n'est pas inférieur à startime.
492

493
        // Démarre une transaction, si ce n'est pas déjà fait.
494
        if ($DB->is_transaction_started() === false) {
2✔
495
            $transaction = $DB->start_delegated_transaction();
2✔
496
        }
497

498
        if (empty($this->id) === true) {
2✔
499
            // Créé le cours.
500
            $newcourse = create_course((object)(array)$this);
2✔
501
            $this->id = $newcourse->id;
2✔
502

503
            // Créé l'instance apsolu_courses.
504
            // Note: insert_record() exige l'absence d'un id.
505
            $sql = "INSERT INTO {apsolu_courses} (id, event, skillid, locationid, weekday, numweekday, starttime, endtime,
2✔
506
                                                  periodid, license, on_homepage, showpolicy, information, informationformat)
507
                                          VALUES (:id, :event, :skillid, :locationid, :weekday, :numweekday, :starttime, :endtime,
508
                                                  :periodid, :license, :onhomepage, :showpolicy, :information, :informationformat)";
2✔
509
            $params = [];
2✔
510
            $params['id'] = $this->id;
2✔
511
            $params['event'] = $this->event;
2✔
512
            $params['skillid'] = $this->skillid;
2✔
513
            $params['locationid'] = $this->locationid;
2✔
514
            $params['weekday'] = $this->weekday;
2✔
515
            $params['numweekday'] = $this->numweekday;
2✔
516
            $params['starttime'] = $this->starttime;
2✔
517
            $params['endtime'] = $this->endtime;
2✔
518
            $params['periodid'] = $this->periodid;
2✔
519
            $params['license'] = $this->license;
2✔
520
            $params['onhomepage'] = $this->on_homepage;
2✔
521
            $params['showpolicy'] = $this->showpolicy;
2✔
522
            $params['information'] = $this->information;
2✔
523
            $params['informationformat'] = $this->informationformat;
2✔
524
            $DB->execute($sql, $params);
2✔
525

526
            // Ajoute une méthode d'inscription manuelle.
527
            $instance = $DB->get_record('enrol', ['enrol' => 'manual', 'courseid' => $this->id]);
2✔
528
            if ($instance === false) {
2✔
529
                $plugin = enrol_get_plugin('manual');
×
530

531
                $fields = $plugin->get_instance_defaults();
×
532

533
                $instance = new stdClass();
×
534
                $instance->id = $plugin->add_instance($newcourse, $fields);
×
535
            }
536

537
            // Ajoute le bloc apsolu_course.
538
            $blocktype = 'apsolu_course';
2✔
539
            $context = context_course::instance($this->id, MUST_EXIST);
2✔
540

541
            $blockinstance = new stdClass();
2✔
542
            $blockinstance->blockname = $blocktype;
2✔
543
            $blockinstance->parentcontextid = $context->id;
2✔
544
            $blockinstance->showinsubcontexts = 0;
2✔
545
            $blockinstance->pagetypepattern = 'course-view-*';
2✔
546
            $blockinstance->subpagepattern = null;
2✔
547
            $blockinstance->defaultregion = 'side-pre'; // Dans la colonne de gauche.
2✔
548
            $blockinstance->defaultweight = -1; // Avant le bloc "Paramètres du cours".
2✔
549
            $blockinstance->configdata = '';
2✔
550
            $blockinstance->timecreated = time();
2✔
551
            $blockinstance->timemodified = time();
2✔
552
            $blockinstance->id = $DB->insert_record('block_instances', $blockinstance);
2✔
553

554
            // Ensure the block context is created.
555
            context_block::instance($blockinstance->id);
2✔
556

557
            // If the new instance was created, allow it to do additional setup.
558
            $block = block_instance($blocktype, $blockinstance);
2✔
559
            $block->instance_create();
2✔
560

561
            // Génére les sessions de cours.
562
            $this->set_sessions();
2✔
563
        } else {
564
            $oldcourse = new course();
2✔
565
            $oldcourse->load($this->id, $required = true);
2✔
566

567
            update_course((object)(array)$this);
2✔
568

569
            $DB->update_record(self::TABLENAME, $this);
2✔
570

571
            // Vérifie que les informations liées aux sessions de cours n'ont pas été modifiées.
572
            $sessionfields = ['locationid', 'weekday', 'numweekday', 'starttime', 'endtime', 'periodid'];
2✔
573
            foreach ($sessionfields as $field) {
2✔
574
                if ($oldcourse->{$field} == $this->{$field}) {
2✔
575
                    continue;
2✔
576
                }
577

578
                // Génère les sessions de cours.
579
                $this->set_sessions();
×
580
                break;
×
581
            }
582
        }
583

584
        // Trie les cours de la catégorie.
585
        $category = core_course_category::get((int) $this->category);
2✔
586
        if ($category->can_resort_courses()) {
2✔
587
            \core_course\management\helper::action_category_resort_courses($category, $sort = 'fullname');
2✔
588
        }
589

590
        // Valide la transaction en cours.
591
        if (isset($transaction) === true) {
2✔
592
            $transaction->allow_commit();
2✔
593
        }
594
    }
595

596
    /**
597
     * Génère ou met à jour le carnet de notes.
598
     *
599
     * @param bool $rescalegrades Témoin indiquant si la note doit être ajustée lorsque la note maximale attendue change.
600
     *
601
     * @return void
602
     */
603
    public function set_gradebook($rescalegrades = false) {
604
        global $DB;
605

606
        // Récupère tous les éléments de notation prévus pour ce cours.
607
        $sql = "SELECT agi.*
×
608
                  FROM {apsolu_grade_items} agi
609
                  JOIN {enrol} e ON agi.calendarid = e.customchar1
610
                 WHERE e.enrol = 'select'
611
                   AND e.courseid = :courseid";
×
612
        $coursegradeitems = $DB->get_records_sql($sql, ['courseid' => $this->id]);
×
613

614
        // Récupère tous les élements de notation actuels de ce cours.
615
        $gradeitems = grade_item::fetch_all(['courseid' => $this->id, 'iteminfo' => gradebook::NAME]);
×
616

617
        if ($gradeitems === false) {
×
618
            $gradeitems = [];
×
619
        }
620

621
        foreach ($gradeitems as $item) {
×
622
            [$apsolugradeid, $itemname] = explode('-', $item->itemname, 2);
×
623

624
            if (isset($coursegradeitems[$apsolugradeid]) === false) {
×
625
                // Supprime un élément de notation obsolète.
626
                $item->delete();
×
627
                continue;
×
628
            }
629

630
            $gradeitem = $coursegradeitems[$apsolugradeid];
×
631
            unset($coursegradeitems[$apsolugradeid]);
×
632

633
            // Met à jour le nom de l'élément de notation.
634
            $item->iteminfo = 'APSOLU';
×
635
            $item->itemname = $gradeitem->id . '-' . $gradeitem->name;
×
636
            $item->set_hidden($gradeitem->publicationdate);
×
637
            $oldmax = $item->grademax;
×
638
            $item->grademax = $gradeitem->grademax;
×
639
            if ($rescalegrades === true) {
×
640
                $oldmin = 0;
×
641
                $newmin = 0;
×
642
                $newmax = $item->grademax;
×
643
                $source = gradebook::SOURCE;
×
644
                $item->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, $source);
×
645
            }
646
            $item->update();
×
647
        }
648

649
        // Enregistre les nouveaux éléments dans le carnet de notes.
650
        $rootcategory = grade_category::fetch_course_category($this->id);
×
651

652
        foreach ($coursegradeitems as $item) {
×
653
            $gradeitem = new grade_item(['id' => 0, 'courseid' => $this->id]);
×
654
            $gradeitem->iteminfo = gradebook::NAME;
×
655
            $gradeitem->itemname = $item->id . '-' . $item->name;
×
656
            $gradeitem->itemtype = 'manual';
×
657
            $gradeitem->categoryid = $rootcategory->id;
×
658
            $gradeitem->hidden = $gradeitem->hidden;
×
659
            $gradeitem->grademax = $gradeitem->grademax;
×
660
            $gradeitem->id = $gradeitem->insert();
×
661
        }
662
    }
663

664
    /**
665
     * Génère les sessions du cours.
666
     *
667
     * @return void
668
     */
669
    public function set_sessions() {
670
        // Récupère le nombre de secondes entre le début de la semaine et la date de début du cours.
671
        $offset = $this->get_session_offset();
2✔
672

673
        $sessions = [];
2✔
674

675
        // Récupère les sessions prévues pour cette période.
676
        $period = new period();
2✔
677
        $period->load($this->periodid);
2✔
678
        foreach ($period->get_sessions($offset) as $sessiontime => $session) {
2✔
679
            if ($session->has_started() === true && defined('APSOLU_DEMO') === false) {
2✔
680
                // On retire de la sélection toutes les sessions déjà passées.
681
                continue;
2✔
682
            }
683

684
            $sessions[$sessiontime] = $session;
2✔
685
        }
686

687
        // Récupère les sessions actuellement définies en base de données pour ce cours.
688
        foreach ($this->get_sessions() as $sessionid => $session) {
2✔
689
            $sessiontime = $session->sessiontime;
2✔
690

691
            if (isset($sessions[$sessiontime]) === true) {
2✔
692
                // La session existe déjà en base de données.
693
                $sessions[$sessiontime] = $session;
2✔
694
                continue;
2✔
695
            }
696

697
            if ($session->has_started() === true) {
2✔
698
                // On conserve toutes les sessions passées.
699
                $sessions[$sessiontime] = $session;
2✔
700
                continue;
2✔
701
            }
702

703
            // Toutes les autres sessions, on les supprime.
704
            $session->delete();
2✔
705
        }
706

707
        // On procède à l'enregistrement des nouvelles sessions.
708
        $count = 0;
2✔
709
        ksort($sessions);
2✔
710
        foreach ($sessions as $sessiontime => $session) {
2✔
711
            $count++;
2✔
712

713
            if ($session->has_started() === true && defined('APSOLU_DEMO') === false) {
2✔
714
                // On ne modifie jamais les sessions passées.
715
                continue;
2✔
716
            }
717

718
            $sessionid = $session->id;
2✔
719
            $sessionname = $session->name;
2✔
720

721
            $session->set_name($count);
2✔
722

723
            if ($sessionid !== 0 && $sessionname === $session->name && $session->locationid === $this->locationid) {
2✔
724
                // La session n'est pas nouvelle, le nom et le lieu sont identiques.
725
                continue;
×
726
            }
727

728
            $session->courseid = $this->id;
2✔
729
            $session->activityid = $this->category; // TODO: supprimer ce champ. Note: category ne semble pas être défini,
2✔
730
                                                    // provoquant une initialisation à 0 en base de données.
731
            $session->locationid = $this->locationid;
2✔
732
            if ($sessionid === 0) {
2✔
733
                $session->timecreated = time();
2✔
734
            }
735
            $session->timemodified = time();
2✔
736
            $session->save();
2✔
737
        }
738
    }
739

740
    /**
741
     * Change la visibilité du cours.
742
     *
743
     * La valeur de retour 1 indique que le cours est visible à la fin de l'exécution de la fonction.
744
     * La valeur de retour 0 indique que le cours est masqué.
745
     *
746
     * @param int|string $courseid Identifiant du cours.
747
     *
748
     * @return int Retourne un entier représentant la visibilité du cours
749
     */
750
    public static function toggle_visibility($courseid) {
751
        $course = new \core_course_list_element(get_course($courseid));
2✔
752

753
        if (empty($course->visible) === true) {
2✔
754
            \core_course\management\helper::action_course_show($course);
2✔
755
            return 1;
2✔
756
        }
757

758
        \core_course\management\helper::action_course_hide($course);
2✔
759
        return 0;
2✔
760
    }
761
}
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