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

apsolu / local_apsolu / 13543905450

25 Feb 2025 04:26PM UTC coverage: 13.189% (-0.008%) from 13.197%
13543905450

push

github

jboulen
feat(attendance): empêche la création de doublons lors de la génération des motifs de présence par défaut

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

66 existing lines in 2 files now uncovered.

651 of 4936 relevant lines covered (13.19%)

0.95 hits per line

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

56.77
/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 int|string $category Entier représentant l'identifiant de l'activité sportive. */
56
    public $category = '';
57

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

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

65
    /** @var string $weekday Jour de la semaine en anglais. Champ à utiliser avec
66
                             la fonction Moodle get_string($weekday, 'calendar'). */
67
    public $weekday = '';
68

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

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

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

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

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

84
    /** @var int|string $locationid Identifiant numérique du lieu de pratique. */
85
    public $locationid = '';
86

87
    /** @var int|string $periodid Identifiant numérique de la période de cours. */
88
    public $periodid = '';
89

90
    /** @var int|string $skillid Identifiant numérique du niveau de pratique. */
91
    public $skillid = '';
92

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

96
    /** @var int|string $informationformat Identifiant numérique du format du texte. */
97
    public $informationformat = FORMAT_HTML;
98

99
    /**
100
     * Affiche une représentation textuelle de l'objet.
101
     *
102
     * @return string.
103
     */
104
    public function __toString() {
UNCOV
105
        return $this->fullname;
×
106
    }
107

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

119
        // Démarre une transaction, si ce n'est pas déjà fait.
120
        if ($DB->is_transaction_started() === false) {
3✔
121
            $transaction = $DB->start_delegated_transaction();
3✔
122
        }
123

124
        // This might take a while. Raise the execution time limit.
125
        core_php_time_limit::raise();
3✔
126

127
        // Supprime les sessions du cours.
128
        foreach ($this->get_sessions() as $session) {
3✔
UNCOV
129
            $session->delete();
×
130
        }
131

132
        // We do this here because it spits out feedback as it goes.
133
        $course = $DB->get_record('course', ['id' => $this->id], $fields = '*', MUST_EXIST);
3✔
134
        $result = delete_course($course, $showfeedback = false);
3✔
135

136
        if ($result === false) {
3✔
UNCOV
137
            $link = new moodle_url('/local/apsolu/courses/index.php', ['tab' => 'courses']);
×
138

UNCOV
139
            throw new moodle_exception('cannotdeletecategorycourse', $module = '', $link, $parameter = $this->fullname);
×
140
        }
141

142
        // Supprime l'objet en base de données.
143
        $DB->delete_records(self::TABLENAME, ['id' => $this->id]);
3✔
144

145
        // TODO: supprimer les notes.
146

147
        // Update course count in categories.
148
        fix_course_sortorder();
3✔
149

150
        // Valide la transaction en cours.
151
        if (isset($transaction) === true) {
3✔
UNCOV
152
            $transaction->allow_commit();
×
153
        }
154

155
        return true;
3✔
156
    }
157

158
    /**
159
     * Retourne l'id du cours de FFSU.
160
     *
161
     * @return int|false Retourne l'id du cours de FFSU ou false si il n'est pas défini.
162
     */
163
    public static function get_federation_courseid() {
UNCOV
164
        debugging('Use of '.__METHOD__.' is deprecated. Use local_apsolu\core\federation\course::get_courseid().', DEBUG_DEVELOPER);
×
165

UNCOV
166
        $federationcourse = get_config('local_apsolu', 'federation_course');
×
167

168
        if (empty($federationcourse) === true) {
×
UNCOV
169
            return false;
×
170
        }
171

UNCOV
172
        return $federationcourse;
×
173
    }
174

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

190
        if (ctype_digit($category) === true) {
12✔
191
            // 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.
192
            $record = $DB->get_record('course_categories', ['id' => $category], $fields = '*', MUST_EXIST);
×
UNCOV
193
            $category = $record->name;
×
194
        }
195

196
        if (ctype_digit($skill) === true) {
12✔
197
            // 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.
198
            $record = $DB->get_record('apsolu_skills', ['id' => $skill], $fields = '*', MUST_EXIST);
×
UNCOV
199
            $skill = $record->name;
×
200
        }
201

202
        $strtime = get_string($weekday, 'calendar').' '.$starttime.' '.$endtime;
12✔
203

204
        if (empty($event) === false) {
12✔
205
            return sprintf('%s %s %s %s', $category, $event, $strtime, $skill);
12✔
206
        }
207

UNCOV
208
        return sprintf('%s %s %s', $category, $strtime, $skill);
×
209
    }
210

211
    /**
212
     * Vérifie le nom abrégé du cours.
213
     *
214
     * Si le nom abrégé passé en paramètre est déjà utilisé, un nouveau nom abrégé est généré.
215
     *
216
     * @param int|string $courseid  Identifiant du cours.
217
     * @param string     $shortname Nom abrégé du cours à contrôler.
218
     *
219
     * @return string Nom abrégé unique.
220
     */
221
    public static function get_shortname($courseid, $shortname) {
222
        global $DB;
223

224
        // Contrôle que le nom abrégé est bien unique.
225
        while (true) {
12✔
226
            $course = $DB->get_record('course', ['shortname' => $shortname]);
12✔
227
            if ($course === false) {
12✔
228
                break;
12✔
229
            }
230

231
            if ($courseid === $course->id) {
3✔
232
                break;
3✔
233
            }
234

235
            $shortname .= '.';
3✔
236
        }
237

238
        return $shortname;
12✔
239
    }
240

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

269
        switch ($day) {
270
            case get_string('monday', 'calendar'):
×
271
                return 1;
×
272
            case get_string('tuesday', 'calendar'):
×
273
                return 2;
×
274
            case get_string('wednesday', 'calendar'):
×
275
                return 3;
×
276
            case get_string('thursday', 'calendar'):
×
277
                return 4;
×
278
            case get_string('friday', 'calendar'):
×
279
                return 5;
×
280
            case get_string('saturday', 'calendar'):
×
281
                return 6;
×
282
            case get_string('sunday', 'calendar'):
×
UNCOV
283
                return 7;
×
284
        }
285

UNCOV
286
        throw new coding_exception('Invalid value ('.json_encode(['day' => $day]).' for '.__METHOD__.'.');
×
287
    }
288

289
    /**
290
     * Recherche et instancie des objets depuis la base de données.
291
     *
292
     * @see Se référer à la documentation de la méthode get_records() de la variable globale $DB.
293
     * @param array|null $conditions Critères de sélection des objets.
294
     * @param string     $sort       Champs par lesquels s'effectue le tri.
295
     * @param string     $fields     Liste des champs retournés.
296
     * @param int        $limitfrom  Retourne les enregistrements à partir de n+$limitfrom.
297
     * @param int        $limitnum   Nombre total d'enregistrements retournés.
298
     *
299
     * @return array Un tableau d'objets instanciés.
300
     */
301
    public static function get_records(?array $conditions = null, string $sort = '', string $fields = '*',
302
                                       int $limitfrom = 0, int $limitnum = 0) {
303
        global $DB;
304

UNCOV
305
        $classname = __CLASS__;
×
306

UNCOV
307
        $records = [];
×
308

309
        foreach ($DB->get_records(get_called_class()::TABLENAME, $conditions, $sort, $fields, $limitfrom, $limitnum) as $data) {
×
310
            $record = new $classname();
×
311
            $record->set_vars($data);
×
UNCOV
312
            $records[$record->id] = $record;
×
313
        }
314

UNCOV
315
        return $records;
×
316
    }
317

318
    /**
319
     * Retourne le nombre de secondes écoulées entre le début de la semaine et le début du cours.
320
     *
321
     * @throws coding_exception Lève une exception lorsque la date de début du cours est mal formatée.
322
     *
323
     * @return int
324
     */
325
    public function get_session_offset() {
326
        if (preg_match('/^[0-9][0-9]:[0-9][0-9]$/', $this->starttime) !== 1) {
15✔
327
            throw new coding_exception('Unexpected value of starttime ('.$this->starttime.') for '.__METHOD__.'.');
3✔
328
        }
329

330
        list($hours, $minutes) = explode(':', $this->starttime);
15✔
331

332
        $offset = 0;
15✔
333
        $offset += (($this->numweekday - 1) * 24 * 60 * 60);
15✔
334
        $offset += ($hours * 60 * 60);
15✔
335
        $offset += ($minutes * 60);
15✔
336

337
        return $offset;
15✔
338
    }
339

340
    /**
341
     * Retourne les sessions du cours.
342
     *
343
     * @return array Retourne un tableau d'objets attendancesession.
344
     */
345
    public function get_sessions() {
346
        return attendancesession::get_records(['courseid' => $this->id]);
12✔
347
    }
348

349
    /**
350
     * Retourne un tableau trié par jour de la semaine et indéxé par le nom du jour en anglais.
351
     *
352
     * @return array Tableau trié et indéxé par le jour de la semaine en anglais.
353
     */
354
    public static function get_weekdays() {
355
        $weekdays = [];
×
356
        $weekdays['monday'] = get_string('monday', 'calendar');
×
357
        $weekdays['tuesday'] = get_string('tuesday', 'calendar');
×
358
        $weekdays['wednesday'] = get_string('wednesday', 'calendar');
×
359
        $weekdays['thursday'] = get_string('thursday', 'calendar');
×
360
        $weekdays['friday'] = get_string('friday', 'calendar');
×
361
        $weekdays['saturday'] = get_string('saturday', 'calendar');
×
UNCOV
362
        $weekdays['sunday'] = get_string('sunday', 'calendar');
×
363

UNCOV
364
        return $weekdays;
×
365
    }
366

367
    /**
368
     * Retourne la durée d'un cours en secondes à partir de son heure de début et son heure de fin.
369
     *
370
     * @param string $starttime Date de début du cours au format hh:mm.
371
     * @param string $endtime   Date de fin du cours au format hh:mm.
372
     *
373
     * @return int|false Durée en secondes du cours, ou false si une erreur est détectée.
374
     */
375
    public static function getDuration(string $starttime, string $endtime) {
376
        $times = [];
×
377
        $times['starttime'] = explode(':', $starttime);
×
UNCOV
378
        $times['endtime'] = explode(':', $endtime);
×
379

380
        foreach ($times as $key => $values) {
×
381
            if (count($values) !== 2) {
×
UNCOV
382
                debugging(__METHOD__.': 2 valeurs attendues pour la variable $'.$key, $level = DEBUG_DEVELOPER);
×
383

UNCOV
384
                return false;
×
385
            }
386

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

UNCOV
390
                return false;
×
391
            }
392

UNCOV
393
            $times[$key] = $values[0] * 60 * 60 + $values[1] * 60;
×
394
        }
395

UNCOV
396
        $duration = $times['endtime'] - $times['starttime'];
×
397

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

UNCOV
401
            return false;
×
402
        }
403

UNCOV
404
        return $duration;
×
405
    }
406

407
    /**
408
     * Charge un objet à partir de son identifiant.
409
     *
410
     * @param int|string $recordid Identifiant de l'objet à charger.
411
     * @param bool       $required Si true, lève une exception lorsque l'objet n'existe pas.
412
                                   Valeur par défaut: false (pas d'exception levée).
413
     *
414
     * @return void
415
     */
416
    public function load($recordid, bool $required = false) {
417
        global $DB;
418

419
        $strictness = IGNORE_MISSING;
6✔
420
        if ($required) {
6✔
421
            $strictness = MUST_EXIST;
3✔
422
        }
423

424
        $sql = "SELECT c.id, c.shortname, c.fullname, c.category, ac.event, ac.skillid, ac.locationid,
6✔
425
                       ac.numweekday, ac.weekday, ac.starttime, ac.endtime, ac.periodid,
426
                       ac.license, ac.on_homepage, ac.showpolicy, ac.information, ac.informationformat
427
                  FROM {course} c
428
                  JOIN {apsolu_courses} ac ON ac.id=c.id
429
                 WHERE c.id = :id";
6✔
430
        $record = $DB->get_record_sql($sql, ['id' => $recordid], $strictness);
6✔
431

432
        if ($record === false) {
6✔
433
            return;
3✔
434
        }
435

436
        $this->set_vars($record);
6✔
437
    }
438

439
    /**
440
     * Enregistre un objet en base de données.
441
     *
442
     * @throws coding_exception A coding exception is thrown when $data parameter is null.
443
     * @throws dml_exception A DML specific exception is thrown for any errors.
444
     *
445
     * @param object|null $data  StdClass représentant l'objet à enregistrer.
446
     * @param object|null $mform Mform représentant un formulaire Moodle nécessaire à la gestion d'un champ de type editor.
447
     *
448
     * @return void
449
     */
450
    public function save(?object $data = null, ?object $mform = null) {
451
        global $DB;
452

453
        if ($data === null) {
15✔
UNCOV
454
            throw new coding_exception('$data parameter cannot be null for '.__METHOD__.'.');
×
455
        }
456

457
        $this->set_vars($data);
15✔
458
        $this->numweekday = self::get_numweekdays($this->weekday);
15✔
459

460
        // Set fullname.
461
        $this->fullname = self::get_fullname($data->str_category, $this->event, $this->weekday,
15✔
462
            $this->starttime, $this->endtime, $data->str_skill);
15✔
463

464
        // Set shortname.
465
        $this->shortname = self::get_shortname($this->id, $this->fullname);
15✔
466

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

469
        // Démarre une transaction, si ce n'est pas déjà fait.
470
        if ($DB->is_transaction_started() === false) {
15✔
471
            $transaction = $DB->start_delegated_transaction();
15✔
472
        }
473

474
        if (empty($this->id) === true) {
15✔
475
            // Créé le cours.
476
            $newcourse = create_course((object)(array)$this);
15✔
477
            $this->id = $newcourse->id;
15✔
478

479
            // Créé l'instance apsolu_courses.
480
            // Note: insert_record() exige l'absence d'un id.
481
            $sql = "INSERT INTO {apsolu_courses} (id, event, skillid, locationid, weekday, numweekday, starttime, endtime,
15✔
482
                                                  periodid, license, on_homepage, showpolicy, information, informationformat)
483
                                          VALUES (:id, :event, :skillid, :locationid, :weekday, :numweekday, :starttime, :endtime,
484
                                                  :periodid, :license, :onhomepage, :showpolicy, :information, :informationformat)";
15✔
485
            $params = [];
15✔
486
            $params['id'] = $this->id;
15✔
487
            $params['event'] = $this->event;
15✔
488
            $params['skillid'] = $this->skillid;
15✔
489
            $params['locationid'] = $this->locationid;
15✔
490
            $params['weekday'] = $this->weekday;
15✔
491
            $params['numweekday'] = $this->numweekday;
15✔
492
            $params['starttime'] = $this->starttime;
15✔
493
            $params['endtime'] = $this->endtime;
15✔
494
            $params['periodid'] = $this->periodid;
15✔
495
            $params['license'] = $this->license;
15✔
496
            $params['onhomepage'] = $this->on_homepage;
15✔
497
            $params['showpolicy'] = $this->showpolicy;
15✔
498
            $params['information'] = $this->information;
15✔
499
            $params['informationformat'] = $this->informationformat;
15✔
500
            $DB->execute($sql, $params);
15✔
501

502
            // Ajoute une méthode d'inscription manuelle.
503
            $instance = $DB->get_record('enrol', ['enrol' => 'manual', 'courseid' => $this->id]);
15✔
504
            if ($instance === false) {
15✔
UNCOV
505
                $plugin = enrol_get_plugin('manual');
×
506

UNCOV
507
                $fields = $plugin->get_instance_defaults();
×
508

509
                $instance = new stdClass();
×
UNCOV
510
                $instance->id = $plugin->add_instance($newcourse, $fields);
×
511
            }
512

513
            // Ajoute le bloc apsolu_course.
514
            $blocktype = 'apsolu_course';
15✔
515
            $context = context_course::instance($this->id, MUST_EXIST);
15✔
516

517
            $blockinstance = new stdClass();
15✔
518
            $blockinstance->blockname = $blocktype;
15✔
519
            $blockinstance->parentcontextid = $context->id;
15✔
520
            $blockinstance->showinsubcontexts = 0;
15✔
521
            $blockinstance->pagetypepattern = 'course-view-*';
15✔
522
            $blockinstance->subpagepattern = null;
15✔
523
            $blockinstance->defaultregion = 'side-pre'; // Dans la colonne de gauche.
15✔
524
            $blockinstance->defaultweight = -1; // Avant le bloc "Paramètres du cours".
15✔
525
            $blockinstance->configdata = '';
15✔
526
            $blockinstance->timecreated = time();
15✔
527
            $blockinstance->timemodified = time();
15✔
528
            $blockinstance->id = $DB->insert_record('block_instances', $blockinstance);
15✔
529

530
            // Ensure the block context is created.
531
            context_block::instance($blockinstance->id);
15✔
532

533
            // If the new instance was created, allow it to do additional setup.
534
            $block = block_instance($blocktype, $blockinstance);
15✔
535
            $block->instance_create();
15✔
536

537
            // Génére les sessions de cours.
538
            $this->set_sessions();
15✔
539
        } else {
540
            $oldcourse = new course();
6✔
541
            $oldcourse->load($this->id, $required = true);
6✔
542

543
            update_course((object)(array)$this);
6✔
544

545
            $DB->update_record(self::TABLENAME, $this);
6✔
546

547
            // Vérifie que les informations liées aux sessions de cours n'ont pas été modifiées.
548
            $sessionfields = ['locationid', 'weekday', 'numweekday', 'starttime', 'endtime', 'periodid'];
6✔
549
            foreach ($sessionfields as $field) {
6✔
550
                if ($oldcourse->{$field} == $this->{$field}) {
6✔
551
                    continue;
6✔
552
                }
553

554
                // Génère les sessions de cours.
555
                $this->set_sessions();
×
UNCOV
556
                break;
×
557
            }
558
        }
559

560
        // Trie les cours de la catégorie.
561
        $category = core_course_category::get((int) $this->category);
15✔
562
        if ($category->can_resort_courses()) {
15✔
563
            \core_course\management\helper::action_category_resort_courses($category, $sort = 'fullname');
15✔
564
        }
565

566
        // Valide la transaction en cours.
567
        if (isset($transaction) === true) {
15✔
568
            $transaction->allow_commit();
15✔
569
        }
570
    }
571

572
    /**
573
     * Génère ou met à jour le carnet de notes.
574
     *
575
     * @param bool $rescalegrades Témoin indiquant si la note doit être ajustée lorsque la note maximale attendue change.
576
     *
577
     * @return void
578
     */
579
    public function set_gradebook($rescalegrades = false) {
580
        global $DB;
581

582
        // Récupère tous les éléments de notation prévus pour ce cours.
583
        $sql = "SELECT agi.*".
×
584
            " FROM {apsolu_grade_items} agi".
×
585
            " JOIN {enrol} e ON agi.calendarid = e.customchar1".
×
586
            " WHERE e.enrol = 'select'".
×
587
            " AND e.courseid = :courseid";
×
UNCOV
588
        $coursegradeitems = $DB->get_records_sql($sql, ['courseid' => $this->id]);
×
589

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

593
        if ($gradeitems === false) {
×
UNCOV
594
            $gradeitems = [];
×
595
        }
596

597
        foreach ($gradeitems as $item) {
×
UNCOV
598
            list($apsolugradeid, $itemname) = explode('-', $item->itemname, 2);
×
599

UNCOV
600
            if (isset($coursegradeitems[$apsolugradeid]) === false) {
×
601
                // Supprime un élément de notation obsolète.
602
                $item->delete();
×
UNCOV
603
                continue;
×
604
            }
605

606
            $gradeitem = $coursegradeitems[$apsolugradeid];
×
UNCOV
607
            unset($coursegradeitems[$apsolugradeid]);
×
608

609
            // Met à jour le nom de l'élément de notation.
610
            $item->iteminfo = 'APSOLU';
×
611
            $item->itemname = $gradeitem->id.'-'.$gradeitem->name;
×
612
            $item->set_hidden($gradeitem->publicationdate);
×
613
            $oldmax = $item->grademax;
×
614
            $item->grademax = $gradeitem->grademax;
×
615
            if ($rescalegrades === true) {
×
616
                $oldmin = 0;
×
617
                $newmin = 0;
×
618
                $newmax = $item->grademax;
×
619
                $source = gradebook::SOURCE;
×
UNCOV
620
                $item->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, $source);
×
621
            }
UNCOV
622
            $item->update();
×
623
        }
624

625
        // Enregistre les nouveaux éléments dans le carnet de notes.
UNCOV
626
        $rootcategory = grade_category::fetch_course_category($this->id);
×
627

628
        foreach ($coursegradeitems as $item) {
×
629
            $gradeitem = new grade_item(['id' => 0, 'courseid' => $this->id]);
×
630
            $gradeitem->iteminfo = gradebook::NAME;
×
631
            $gradeitem->itemname = $item->id.'-'.$item->name;
×
632
            $gradeitem->itemtype = 'manual';
×
633
            $gradeitem->categoryid = $rootcategory->id;
×
634
            $gradeitem->hidden = $gradeitem->hidden;
×
635
            $gradeitem->grademax = $gradeitem->grademax;
×
UNCOV
636
            $gradeitem->id = $gradeitem->insert();
×
637
        }
638
    }
639

640
    /**
641
     * Génère les sessions du cours.
642
     *
643
     * @return void
644
     */
645
    public function set_sessions() {
646
        // Récupère le nombre de secondes entre le début de la semaine et la date de début du cours.
647
        $offset = $this->get_session_offset();
15✔
648

649
        $sessions = [];
15✔
650

651
        // Récupère les sessions prévues pour cette période.
652
        $period = new period();
15✔
653
        $period->load($this->periodid);
15✔
654
        foreach ($period->get_sessions($offset) as $sessiontime => $session) {
15✔
655
            if ($session->is_expired() === true && defined('APSOLU_DEMO') === false) {
3✔
656
                // On retire de la sélection toutes les sessions déjà passées.
657
                continue;
3✔
658
            }
659

660
            $sessions[$sessiontime] = $session;
3✔
661
        }
662

663
        // Récupère les sessions actuellement définies en base de données pour ce cours.
664
        foreach ($this->get_sessions() as $sessionid => $session) {
15✔
665
            $sessiontime = $session->sessiontime;
3✔
666

667
            if (isset($sessions[$sessiontime]) === true) {
3✔
668
                // La session existe déjà en base de données.
669
                $sessions[$sessiontime] = $session;
3✔
670
                continue;
3✔
671
            }
672

673
            if ($session->is_expired() === true) {
3✔
674
                // On conserve toutes les sessions passées.
675
                $sessions[$sessiontime] = $session;
3✔
676
                continue;
3✔
677
            }
678

679
            // Toutes les autres sessions, on les supprime.
680
            $session->delete();
3✔
681
        }
682

683
        // On procède à l'enregistrement des nouvelles sessions.
684
        $count = 0;
15✔
685
        ksort($sessions);
15✔
686
        foreach ($sessions as $sessiontime => $session) {
15✔
687
            $count++;
3✔
688

689
            if ($session->is_expired() === true && defined('APSOLU_DEMO') === false) {
3✔
690
                // On ne modifie jamais les sessions passées.
691
                continue;
3✔
692
            }
693

694
            $sessionid = $session->id;
3✔
695
            $sessionname = $session->name;
3✔
696

697
            $session->set_name($count);
3✔
698

699
            if ($sessionid !== 0 && $sessionname === $session->name && $session->locationid === $this->locationid) {
3✔
700
                // La session n'est pas nouvelle, le nom et le lieu sont identiques.
701
                continue;
3✔
702
            }
703

704
            $session->courseid = $this->id;
3✔
705
            $session->activityid = $this->category; // TODO: supprimer ce champ. Note: category ne semble pas être défini,
3✔
706
                                                    // provoquant une initialisation à 0 en base de données.
707
            $session->locationid = $this->locationid;
3✔
708
            if ($sessionid === 0) {
3✔
709
                $session->timecreated = time();
3✔
710
            }
711
            $session->timemodified = time();
3✔
712
            $session->save();
3✔
713
        }
714
    }
715

716
    /**
717
     * Change la visibilité du cours.
718
     *
719
     * La valeur de retour 1 indique que le cours est visible à la fin de l'exécution de la fonction.
720
     * La valeur de retour 0 indique que le cours est masqué.
721
     *
722
     * @param int|string $courseid Identifiant du cours.
723
     *
724
     * @return int Retourne un entier représentant la visibilité du cours
725
     */
726
    public static function toggle_visibility($courseid) {
727
        $course = new \core_course_list_element(get_course($courseid));
3✔
728

729
        if (empty($course->visible) === true) {
3✔
730
            \core_course\management\helper::action_course_show($course);
3✔
731
            return 1;
3✔
732
        }
733

734
        \core_course\management\helper::action_course_hide($course);
3✔
735
        return 0;
3✔
736
    }
737
}
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