2023-09-08 10:12:23 +02:00
< ? php
/**
* This file is part of Zwii .
* For full copyright and license information , please see the LICENSE
* file that was distributed with this source code .
*
* @ author Rémi Jean < remi . jean @ outlook . com >
* @ copyright Copyright ( C ) 2008 - 2018 , Rémi Jean
* @ author Frédéric Tempez < frederic . tempez @ outlook . com >
* @ copyright Copyright ( C ) 2018 - 2023 , Frédéric Tempez
* @ license CC Attribution - NonCommercial - NoDerivatives 4.0 International
* @ link http :// zwiicms . fr /
*/
2023-09-08 22:09:25 +02:00
class course extends common
2023-09-08 10:12:23 +02:00
{
public static $actions = [
2023-09-12 22:16:25 +02:00
'index' => self :: GROUP_ADMIN ,
'edit' => self :: GROUP_ADMIN ,
2023-09-08 22:09:25 +02:00
'add' => self :: GROUP_ADMIN ,
2023-09-12 22:16:25 +02:00
'delete' => self :: GROUP_ADMIN ,
2023-09-21 21:19:39 +02:00
'swap' => self :: GROUP_VISITOR ,
2023-09-26 21:26:34 +02:00
'enrol' => self :: GROUP_VISITOR ,
2023-09-08 10:12:23 +02:00
];
2023-09-08 22:09:25 +02:00
public static $courseAccess = [
2023-09-20 22:02:42 +02:00
self :: COURSE_ACCESS_OPEN => 'Ouvert' ,
self :: COURSE_ACCESS_DATE => 'Période d\'ouverture' ,
self :: COURSE_ACCESS_CLOSE => 'Fermé' ,
2023-09-08 22:09:25 +02:00
];
public static $courseEnrolment = [
2023-09-20 22:02:42 +02:00
self :: COURSE_ENROLMENT_GUEST => 'Anonyme' ,
self :: COURSE_ENROLMENT_SELF => 'Auto-inscrition libre' ,
self :: COURSE_ENROLMENT_SELF_KEY => 'Auto-inscription avec clé' ,
self :: COURSE_ENROLMENT_MANUAL => 'Manuelle'
2023-09-08 22:09:25 +02:00
];
public static $courseTeachers = [];
2023-09-29 04:28:17 +02:00
public static $courseCategories = [];
2023-09-12 22:16:25 +02:00
public static $courses = [];
2023-09-23 19:23:41 +02:00
public static $swapMessage = [];
2023-09-20 22:02:42 +02:00
2023-09-17 17:12:53 +02:00
2023-09-08 10:12:23 +02:00
public function index ()
{
2023-09-12 22:16:25 +02:00
$courseIdShortTitle = helper :: arrayColumn ( $this -> getData ([ 'course' ]), 'shortTitle' );
2023-09-16 17:27:22 +02:00
ksort ( $courseIdShortTitle );
2023-09-12 22:16:25 +02:00
foreach ( $courseIdShortTitle as $courseId => $courseTitle ) {
self :: $courses [] = [
$courseTitle ,
$this -> getData ([ 'course' , $courseId , 'author' ]),
$this -> getData ([ 'course' , $courseId , 'description' ]),
template :: button ( 'courseEdit' . $courseId , [
'href' => helper :: baseUrl () . 'course/edit/' . $courseId ,
'value' => template :: ico ( 'pencil' ),
'help' => 'Éditer'
]),
template :: button ( 'courseDelete' . $courseId , [
'class' => 'courseDelete buttonRed' ,
'href' => helper :: baseUrl () . 'course/delete/' . $courseId ,
'value' => template :: ico ( 'trash' ),
'help' => 'Supprimer'
])
];
}
2023-09-16 17:27:22 +02:00
//var_dump($this->getCourseHierarchy(1, 1));
2023-09-08 22:09:25 +02:00
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Cours' ),
'view' => 'index'
]);
}
2023-09-11 22:39:19 +02:00
/**
* Ajoute un nouveau cours
*/
2023-09-08 22:09:25 +02:00
public function add ()
{
// Soumission du formulaire
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === true &&
$this -> isPost ()
) {
2023-09-11 22:39:19 +02:00
$courseId = uniqid ();
2023-09-16 17:27:22 +02:00
$author = $this -> getInput ( 'courseAddAuthor' );
2023-09-08 22:09:25 +02:00
$this -> setData ([
'course' ,
2023-09-11 22:39:19 +02:00
$courseId ,
2023-09-08 22:09:25 +02:00
[
2023-09-11 22:39:19 +02:00
'title' => $this -> getInput ( 'courseAddTitle' , helper :: FILTER_STRING_SHORT , true ),
'shortTitle' => $this -> getInput ( 'courseAddShortTitle' , helper :: FILTER_STRING_SHORT , true ),
2023-09-16 17:27:22 +02:00
'author' => $author ,
2023-09-08 22:09:25 +02:00
'description' => $this -> getInput ( 'courseAddDescription' , helper :: FILTER_STRING_SHORT , true ),
2023-09-21 15:34:03 +02:00
'access' => $this -> getInput ( 'courseAddAccess' , helper :: FILTER_INT ),
2023-09-11 22:39:19 +02:00
'openingDate' => $this -> getInput ( 'courseOpeningDate' , helper :: FILTER_DATETIME ),
'closingDate' => $this -> getInput ( 'courseClosingDate' , helper :: FILTER_DATETIME ),
2023-09-21 15:34:03 +02:00
'enrolment' => $this -> getInput ( 'courseAddEnrolment' , helper :: FILTER_INT ),
2023-09-08 22:09:25 +02:00
'enrolmentKey' => $this -> getInput ( 'courseAddEnrolmentKey' ),
]
]);
2023-09-08 10:12:23 +02:00
2023-09-11 22:39:19 +02:00
// Créer la structure de données
mkdir ( self :: DATA_DIR . $courseId );
2023-09-21 11:34:42 +02:00
$this -> initDB ( 'page' , $courseId );
$this -> initDB ( 'module' , $courseId );
$this -> initData ( 'page' , $courseId );
$this -> initData ( 'module' , $courseId );
2023-09-16 17:27:22 +02:00
2023-09-11 22:39:19 +02:00
// BDD des inscrits
2023-09-16 17:27:22 +02:00
$this -> setData ([
'enrolment' ,
$courseId ,
2023-09-21 19:32:30 +02:00
[]
2023-09-16 17:27:22 +02:00
]);
2023-09-11 22:39:19 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'notification' => helper :: translate ( 'Cours créé' ),
'state' => true
]);
2023-09-08 22:09:25 +02:00
}
2023-09-11 22:39:19 +02:00
// Liste des enseignants pour le sélecteur d'auteurs
2023-09-08 22:09:25 +02:00
$teachers = $this -> getData ([ 'user' ]);
foreach ( $teachers as $teacherId => $teacherInfo ) {
2023-09-11 22:39:19 +02:00
if ( $teacherInfo [ " group " ] >= 2 ) {
2023-09-08 22:09:25 +02:00
self :: $courseTeachers [ $teacherId ] = $teacherInfo [ " firstname " ] . ' ' . $teacherInfo [ " lastname " ];
}
}
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Ajouter un cours' ),
'view' => 'add'
]);
2023-09-08 10:12:23 +02:00
}
2023-09-08 22:09:25 +02:00
2023-09-29 04:28:17 +02:00
2023-09-12 22:16:25 +02:00
/**
* Edite un cours
*/
public function edit ()
{
// Soumission du formulaire
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === true &&
$this -> isPost ()
) {
$courseId = $this -> getUrl ( 2 );
2023-09-16 17:27:22 +02:00
$author = $this -> getInput ( 'courseAddAuthor' );
2023-09-12 22:16:25 +02:00
$this -> setData ([
'course' ,
$courseId ,
[
'title' => $this -> getInput ( 'courseEditTitle' , helper :: FILTER_STRING_SHORT , true ),
'shortTitle' => $this -> getInput ( 'courseEditShortTitle' , helper :: FILTER_STRING_SHORT , true ),
2023-09-16 18:50:23 +02:00
'author' => $author ,
2023-09-12 22:16:25 +02:00
'description' => $this -> getInput ( 'courseEditDescription' , helper :: FILTER_STRING_SHORT , true ),
2023-09-16 17:27:22 +02:00
'access' => $this -> getInput ( 'courseEditAccess' , helper :: FILTER_INT ),
2023-09-12 22:16:25 +02:00
'openingDate' => $this -> getInput ( 'courseOpeningDate' , helper :: FILTER_DATETIME ),
'closingDate' => $this -> getInput ( 'courseClosingDate' , helper :: FILTER_DATETIME ),
2023-09-16 17:27:22 +02:00
'enrolment' => $this -> getInput ( 'courseEditEnrolment' , helper :: FILTER_INT ),
2023-09-12 22:16:25 +02:00
'enrolmentKey' => $this -> getInput ( 'courseEditEnrolmentKey' ),
]
]);
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'notification' => helper :: translate ( 'Cours édité' ),
'state' => true
]);
}
// Liste des enseignants pour le sélecteur d'auteurs
$teachers = $this -> getData ([ 'user' ]);
foreach ( $teachers as $teacherId => $teacherInfo ) {
if ( $teacherInfo [ " group " ] >= 2 ) {
self :: $courseTeachers [ $teacherId ] = $teacherInfo [ " firstname " ] . ' ' . $teacherInfo [ " lastname " ];
}
}
2023-09-29 04:28:17 +02:00
self :: $courseCategories = $this -> getData ([ 'categorie' ]);
2023-09-12 22:16:25 +02:00
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Editer un cours' ),
'view' => 'edit'
]);
}
2023-09-29 04:28:17 +02:00
public function delete ()
{
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ||
// Le cours n'existe pas
$this -> getData ([ 'course' , $this -> getUrl ( 2 )]) === null
// Groupe insuffisant
and ( $this -> getUrl ( 'group' ) < self :: GROUP_EDITOR )
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
// Suppression
} else {
$this -> deleteData ([ 'course' , $this -> getUrl ( 2 )]);
$this -> deleteData ([ 'enrolment' , $this -> getUrl ( 2 )]);
if ( is_dir ( self :: DATA_DIR . $this -> getUrl ( 2 ))) {
$this -> deleteDir ( self :: DATA_DIR . $this -> getUrl ( 2 ));
}
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'notification' => helper :: translate ( 'Cours supprimé' ),
'state' => true
]);
}
}
2023-09-21 15:34:03 +02:00
/*
* Affiche un écran de connexion à un cours
*/
public function change ()
{
// Soumission du formulaire
if (
$this -> isPost () ||
$this -> getUrl ( 2 ) === 'home'
2023-09-21 19:32:30 +02:00
2023-09-21 15:34:03 +02:00
) {
$this -> swap ();
}
2023-09-21 19:32:30 +02:00
// Bouton de connexion ou d'inscription
// C'est un prof ou un admin
2023-09-22 19:33:03 +02:00
self :: $changeMessages = $this -> getUser ( 'group' ) >= self :: GROUP_EDITOR
? 'Se connecter'
// C'est un étudiant ou un visiteur
: '' ;
2023-09-21 19:32:30 +02:00
2023-09-21 15:34:03 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-09-21 19:32:30 +02:00
'title' => sprintf ( helper :: translate ( 'Accéder au cours %s' ), $this -> getData ([ 'course' , $this -> getUrl ( 2 ), 'shortTitle' ])),
2023-09-21 15:34:03 +02:00
'view' => 'change' ,
'display' => self :: DISPLAY_LAYOUT_LIGHT ,
]);
}
2023-09-11 22:39:19 +02:00
/*
* Traitement du changement de langue
* Fonction utilisée par le noyau
*/
public function swap ()
2023-09-26 21:26:34 +02:00
{
$courseId = $this -> getUrl ( 2 );
$message = '' ;
2023-09-29 03:56:12 +02:00
$redirect = helper :: baseUrl ();
2023-09-26 21:26:34 +02:00
$state = true ;
2023-09-29 03:56:12 +02:00
2023-09-26 21:26:34 +02:00
if (
// Sortir du cours et afficher l'accueil
$courseId === 'home'
2023-09-27 21:01:11 +02:00
) {
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
2023-09-29 03:56:12 +02:00
}
2023-09-29 04:20:09 +02:00
// l'étudiant est inscrit dans le cours ET le cours est ouvert
2023-09-27 21:01:11 +02:00
elseif (
2023-09-29 03:56:12 +02:00
$this -> courseIsUserEnroled ( $courseId )
&& $this -> courseIsAvailable ( $courseId )
2023-09-26 21:26:34 +02:00
) {
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
$message = sprintf ( helper :: translate ( 'Bienvenue dans le cours %s' ), $this -> getData ([ 'course' , $courseId , 'shortTitle' ]));
}
// Le cours est fermé
2023-09-27 21:01:11 +02:00
elseif ( $this -> courseIsAvailable ( $courseId ) === false ) {
2023-09-26 21:26:34 +02:00
// Génération du message
2023-09-29 03:56:12 +02:00
$message = helper :: translate ( 'Ce cours est fermé' );
$state = false ;
2023-09-26 21:26:34 +02:00
if ( $this -> getData ([ 'course' , $courseId , 'access' ]) === self :: COURSE_ACCESS_DATE ) {
$from = helper :: dateUTF8 ( '%m %B %Y' , $this -> getData ([ 'course' , $courseId , 'openingDate' ])) . helper :: translate ( ' à ' ) . helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'course' , $courseId , 'openingDate' ]));
$to = helper :: dateUTF8 ( '%m %B %Y' , $this -> getData ([ 'course' , $courseId , 'closingDate' ])) . helper :: translate ( ' à ' ) . helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'course' , $courseId , 'closingDate' ]));
$message = sprintf ( helper :: translate ( 'Ce cours ouvre le <br>%s <br> et ferme le %s' ), $from , $to );
}
}
2023-09-29 04:20:09 +02:00
// le cours est ouvert, l'étudiant n'est pas inscrit, l'accès au cours est anonyme
elseif (
$this -> courseIsAvailable ( $courseId ) &&
$this -> courseIsUserEnroled ( $courseId ) === false
) {
// Gérer les modalités d'inscription
switch ( $this -> getData ([ 'course' , $courseId , 'enrolment' ])) {
// Anonyme
case self :: COURSE_ENROLMENT_GUEST :
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
break ;
// Auto avec ou sans clé
case self :: COURSE_ENROLMENT_SELF :
case self :: COURSE_ENROLMENT_SELF_KEY :
//L'étudiant dispsoe d'un compte
if ( $this -> getUser ( 'id' )) {
$redirect = $redirect . 'course/enrol/' . $courseId ;
$message = helper :: translate ( 'Veuillez vous inscrire' );
$state = true ;
} else {
$message = helper :: translate ( 'Vous devez disposer d\'un compte pour accéder à ce cours' );
$state = false ;
}
break ;
// Par le prof
case self :: COURSE_ENROLMENT_MANUAL :
$message = helper :: translate ( 'L\'enseignant ne vous pas inscrit !' );
$state = false ;
break ;
default :
# code...
break ;
}
}
2023-09-26 21:26:34 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => $redirect ,
'notification' => helper :: translate ( $message ),
'state' => $state ,
]);
}
// Génération du message d'inscription
public function enrol ()
2023-09-11 22:39:19 +02:00
{
$courseId = $this -> getUrl ( 2 );
2023-09-23 19:23:41 +02:00
$userId = $this -> getUser ( 'id' );
2023-09-25 21:18:06 +02:00
// Soumission du formulaire
if (
$this -> isPost ()
) {
if (
$this -> courseIsAvailable ( $courseId )
) {
// Inscrit l'étudiant
switch ( $this -> getData ([ 'course' , $courseId , 'enrolment' ])) {
case self :: COURSE_ENROLMENT_SELF :
$this -> courseEnrolUser ( $courseId , $userId );
break ;
case self :: COURSE_ENROLMENT_SELF_KEY :
if ( $this -> getInput ( 'courseSwapEnrolmentKey' ) === $this -> getData ([ 'course' , $courseId , 'enrolmentKey' ])) {
$this -> courseEnrolUser ( $courseId , $userId );
}
break ;
}
// Stocker la sélection
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl ()
]);
}
}
// L'étudiant est-il inscrit
self :: $swapMessage [ 'submitLabel' ] = 'Se connecter' ;
self :: $swapMessage [ 'enrolmentMessage' ] = '' ;
self :: $swapMessage [ 'enrolmentKey' ] = '' ;
if ( $this -> courseIsUserEnroled ( $courseId ) === false ) {
switch ( $this -> getData ([ 'course' , $courseId , 'enrolment' ])) {
case self :: COURSE_ENROLMENT_GUEST :
case self :: COURSE_ENROLMENT_SELF :
self :: $swapMessage [ 'submitLabel' ] = helper :: translate ( 'M\'inscrire' );
break ;
case self :: COURSE_ENROLMENT_SELF_KEY :
if ( $userId ) {
self :: $swapMessage [ 'enrolmentKey' ] = template :: text ( 'courseSwapEnrolmentKey' , [
'label' => helper :: translate ( 'Clé d\'inscription' ),
]);
} else {
2023-09-23 19:23:41 +02:00
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Connectez-vous pour accèder à ce cours.' );
2023-09-25 21:18:06 +02:00
}
break ;
case self :: COURSE_ENROLMENT_MANUAL :
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'L\'enseignant inscrit les étudiants dans le cours, vous ne pouvez pas vous inscrire vous-même.' );
break ;
2023-09-22 19:33:03 +02:00
}
// Valeurs en sortie
$this -> addOutput ([
'title' => sprintf ( helper :: translate ( 'Accéder au cours %s' ), $this -> getData ([ 'course' , $this -> getUrl ( 2 ), 'shortTitle' ])),
2023-09-26 21:26:34 +02:00
'view' => 'enrol' ,
2023-09-22 19:33:03 +02:00
'display' => self :: DISPLAY_LAYOUT_LIGHT ,
]);
2023-09-11 22:39:19 +02:00
}
2023-09-25 21:18:06 +02:00
}
2023-09-22 19:33:03 +02:00
2023-09-25 21:18:06 +02:00
/**
* Autorise l ' accès à un cours
* @ param @ return bool le user a le droit d ' entrée dans le cours
* @ param string $userId identifiant de l ' utilisateur
* @ param string $courseId identifiant du cours sollicité
*/
2023-09-26 21:26:34 +02:00
public function courseIsUserEnroled ( $courseId )
2023-09-25 21:18:06 +02:00
{
$userId = $this -> getUser ( 'id' );
2023-09-27 21:01:11 +02:00
$group = $userId ? $this -> getData ([ 'user' , $userId , 'group' ]) : null ;
2023-09-25 21:18:06 +02:00
switch ( $group ) {
case self :: GROUP_ADMIN :
$r = true ;
break ;
case self :: GROUP_EDITOR :
$r = in_array ( $userId , array_keys ( $this -> getData ([ 'enrolment' , $courseId ])));
break ;
case self :: GROUP_MEMBER :
$r = in_array ( $userId , array_keys ( $this -> getData ([ 'enrolment' , $courseId ])));
break ;
// Visiteur non connecté
case self :: GROUP_VISITOR :
2023-09-27 21:01:11 +02:00
case null :
2023-09-25 21:18:06 +02:00
$r = $this -> getData ([ 'course' , $courseId , 'enrolment' ]) === self :: COURSE_ENROLMENT_GUEST ;
break ;
default :
$r = false ;
}
return $r ;
}
2023-09-22 19:33:03 +02:00
2023-09-26 21:26:34 +02:00
public function courseEnrolUser ( $courseId , $userId )
2023-09-25 21:18:06 +02:00
{
$this -> setData ([
'enrolment' ,
$courseId ,
$userId ,
[
'lastPageId' => '' ,
'lastVisit' => 0
]
]);
2023-09-11 22:39:19 +02:00
}
2023-09-11 21:45:31 +02:00
2023-09-25 21:18:06 +02:00
/**
* Autorise l ' accès à un cours
* @ param @ return bool le user a le droit d ' entrée dans le cours
* @ param string $courseId identifiant du cours sollicité
*/
2023-09-26 21:26:34 +02:00
public function courseIsAvailable ( $courseId )
2023-09-25 21:18:06 +02:00
{
if ( $courseId === 'home' ) {
return true ;
}
$access = $this -> getData ([ 'course' , $courseId , 'access' ]);
switch ( $access ) {
case self :: COURSE_ACCESS_OPEN :
return true ;
case self :: COURSE_ACCESS_DATE :
return (
time () >= $this -> getData ([ 'course' , $courseId , 'openingDate' ]) &&
time () <= $this -> getData ([ 'course' , $courseId , 'closingDate' ])
);
case self :: COURSE_ACCESS_CLOSE :
return false ;
}
}
2023-09-21 15:34:03 +02:00
2023-09-08 10:12:23 +02:00
}