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-29 04:49:13 +02:00
'swap' => self :: GROUP_VISITOR ,
2023-10-19 17:23:34 +02:00
'suscribe' => self :: GROUP_VISITOR ,
2023-10-26 13:51:19 +02:00
'unsuscribe' => self :: GROUP_MEMBER ,
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-29 04:49:13 +02:00
'category' => self :: GROUP_ADMIN ,
'categoryAdd' => self :: GROUP_ADMIN ,
2023-10-04 21:05:39 +02:00
'categoryDelete' => self :: GROUP_ADMIN ,
'user' => self :: GROUP_ADMIN ,
2023-10-04 22:04:18 +02:00
'userAdd' => self :: GROUP_ADMIN ,
2023-10-07 18:30:43 +02:00
'userDelete' => self :: GROUP_ADMIN ,
2023-10-08 14:46:44 +02:00
'userDeleteAll' => self :: GROUP_ADMIN ,
2023-10-18 13:41:16 +02:00
'userHistory' => self :: GROUP_ADMIN ,
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-10-19 15:40:24 +02:00
self :: COURSE_ENROLMENT_GUEST => 'Anonyme' ,
2023-10-06 20:20:55 +02:00
self :: COURSE_ENROLMENT_SELF => 'Inscription libre' ,
self :: COURSE_ENROLMENT_SELF_KEY => 'Inscription avec clé' ,
2023-10-06 17:46:56 +02:00
//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-10-04 22:04:18 +02:00
public static $courseUsers = [];
2023-10-09 13:47:11 +02:00
public static $alphabet = [];
2023-10-09 19:10:48 +02:00
public static $courseGroups = [
2023-10-09 19:40:59 +02:00
'all' => 'Tout'
2023-10-09 13:47:11 +02:00
];
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-10-04 17:57:07 +02:00
public static $pagesList = [ 'accueil' => 'Accueil' ];
2023-09-30 13:35:20 +02:00
2023-09-17 17:12:53 +02:00
2023-10-18 13:41:16 +02:00
public static $userHistory = [];
2023-09-08 10:12:23 +02:00
public function index ()
{
2023-10-19 14:35:12 +02:00
$courseIdShortTitle = helper :: arrayColumn ( $this -> getData ([ 'course' ]), 'title' );
2023-09-16 17:27:22 +02:00
ksort ( $courseIdShortTitle );
2023-09-12 22:16:25 +02:00
foreach ( $courseIdShortTitle as $courseId => $courseTitle ) {
2023-10-26 13:51:19 +02:00
$categorieUrl = helper :: baseUrl ( ! helper :: checkRewrite ()) . 'course/suscribe/' . $courseId ;
2023-09-30 19:04:55 +02:00
$authorId = $this -> getData ([ 'course' , $courseId , 'author' ]);
$author = sprintf ( '%s %s' , $this -> getData ([ 'user' , $authorId , 'firstname' ]), $this -> getData ([ 'user' , $authorId , 'lastname' ]));
$access = self :: $courseAccess [ $this -> getData ([ 'course' , $courseId , 'access' ])];
$enrolment = self :: $courseEnrolment [ $this -> getData ([ 'course' , $courseId , 'enrolment' ])];
$description = sprintf ( '%s<br />%s<br />%s<br />' , $this -> getData ([ 'course' , $courseId , 'description' ]), $access , $enrolment );
2023-09-12 22:16:25 +02:00
self :: $courses [] = [
$courseTitle ,
2023-09-30 19:04:55 +02:00
$author ,
$description ,
2023-09-30 13:35:20 +02:00
'<a href="' . $categorieUrl . '" target="_blank">' . $categorieUrl . '</a>' ,
2023-10-04 22:04:18 +02:00
template :: button ( 'categoryUser' . $courseId , [
'href' => helper :: baseUrl () . 'course/user/' . $courseId ,
'value' => template :: ico ( 'users' ),
'help' => 'Inscrits'
]),
2023-09-12 22:16:25 +02:00
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-29 04:49:13 +02:00
2023-09-08 22:09:25 +02:00
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Cours' ),
2023-10-21 13:55:14 +02:00
'view' => 'index' ,
'vendor' => [
'datatables'
]
2023-09-08 22:09:25 +02:00
]);
}
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-10-04 17:57:07 +02:00
// Créer la structure de données
mkdir ( self :: DATA_DIR . $courseId );
$this -> initDB ( 'page' , $courseId );
$this -> initDB ( 'module' , $courseId );
$this -> initDB ( 'theme' , $courseId );
$this -> initData ( 'page' , $courseId );
$this -> initData ( 'module' , $courseId );
$this -> initData ( 'theme' , $courseId );
// BDD des inscrits
$this -> setData ([
'enrolment' ,
$courseId ,
[]
]);
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 ),
2023-10-19 14:35:12 +02:00
'title' => $this -> getInput ( 'courseAddShortTitle' , helper :: FILTER_STRING_SHORT , true ),
2023-09-30 13:35:20 +02:00
'author' => $this -> getInput ( 'courseAddAuthor' ),
2023-10-04 17:58:58 +02:00
'homePageId' => 'accueil' ,
2023-09-30 13:35:20 +02:00
'category' => $this -> getInput ( 'courseAddCategories' ),
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
// 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 " ];
}
}
2023-09-29 04:49:13 +02:00
// Liste des catégories de cours
self :: $courseCategories = $this -> getData ([ 'category' ]);
2023-09-08 22:09:25 +02:00
// 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-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 );
$this -> setData ([
'course' ,
$courseId ,
[
2023-10-19 14:35:12 +02:00
'title' => $this -> getInput ( 'courseEditShortTitle' , helper :: FILTER_STRING_SHORT , true ),
2023-09-30 13:35:20 +02:00
'author' => $this -> getInput ( 'courseEditAuthor' ),
'homePageId' => $this -> getInput ( 'courseEditHomePageId' ),
'category' => $this -> getInput ( 'courseEditCategories' ),
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:49:13 +02:00
// Liste des catégories de cours
self :: $courseCategories = $this -> getData ([ 'category' ]);
2023-09-12 22:16:25 +02:00
2023-09-30 13:35:20 +02:00
// Liste des pages disponibles
2023-10-03 14:56:33 +02:00
$this -> initDB ( 'page' , $this -> getUrl ( 2 ));
2023-09-30 13:35:20 +02:00
self :: $pagesList = $this -> getData ([ 'page' ]);
foreach ( self :: $pagesList as $page => $pageId ) {
if (
$this -> getData ([ 'page' , $page , 'block' ]) === 'bar' ||
$this -> getData ([ 'page' , $page , 'disable' ]) === true
) {
unset ( self :: $pagesList [ $page ]);
}
}
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 ()
{
2023-10-04 17:57:07 +02:00
$courseId = $this -> getUrl ( 2 );
2023-09-29 04:28:17 +02:00
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ||
// Le cours n'existe pas
2023-10-04 17:57:07 +02:00
$this -> getData ([ 'course' , $courseId ]) === null
2023-09-29 04:28:17 +02:00
// Groupe insuffisant
and ( $this -> getUrl ( 'group' ) < self :: GROUP_EDITOR )
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
// Suppression
} else {
2023-10-04 18:01:04 +02:00
// Active l'accueil
2023-10-04 18:22:47 +02:00
$_SESSION [ 'ZWII_SITE_CONTENT' ] = 'home' ;
2023-10-04 21:05:39 +02:00
2023-10-04 18:01:04 +02:00
// ET efface la structure
2023-10-04 17:57:07 +02:00
if ( is_dir ( self :: DATA_DIR . $courseId )) {
$success = $this -> deleteDir ( self :: DATA_DIR . $courseId );
$this -> deleteData ([ 'course' , $courseId ]);
$this -> deleteData ([ 'enrolment' , $courseId ]);
}
2023-09-29 04:28:17 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
2023-10-04 17:57:07 +02:00
'notification' => $success ? helper :: translate ( 'Cours supprimé' ) : helper :: translate ( 'Erreur de suppression' ),
'state' => $success
2023-09-29 04:28:17 +02:00
]);
}
}
2023-09-29 04:49:13 +02:00
/**
* Liste les catégories d ' un cours
2023-09-21 15:34:03 +02:00
*/
2023-09-29 04:49:13 +02:00
public function category ()
2023-09-21 15:34:03 +02:00
{
2023-09-30 09:18:08 +02:00
$categories = $this -> getData ([ 'category' ]);
ksort ( $categories );
foreach ( $categories as $categoryId => $categoryTitle ) {
self :: $courseCategories [] = [
$categoryId ,
$categoryTitle ,
2023-10-04 21:05:39 +02:00
template :: button ( 'categoryEdit' . $categoryId , [
2023-09-30 09:18:08 +02:00
'href' => helper :: baseUrl () . 'course/categoryEdit/' . $categoryId ,
'value' => template :: ico ( 'pencil' ),
'help' => 'Éditer'
]),
template :: button ( 'courseDelete' . $categoryId , [
2023-10-04 21:05:39 +02:00
'class' => 'categoryDelete buttonRed' ,
2023-09-30 09:18:08 +02:00
'href' => helper :: baseUrl () . 'course/categoryDelete/' . $categoryId ,
'value' => template :: ico ( 'trash' ),
'help' => 'Supprimer'
])
];
}
2023-09-21 15:34:03 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-10-04 22:04:18 +02:00
'title' => helper :: translate ( 'Catégorie de cours' ),
2023-09-29 04:49:13 +02:00
'view' => 'category'
2023-09-21 15:34:03 +02:00
]);
}
2023-10-04 21:05:39 +02:00
public function categoryAdd ()
{
// Soumission du formulaire
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === true &&
$this -> isPost ()
) {
$categoryId = $this -> getInput ( 'categoryAddTitle' , helper :: FILTER_ID , true );
$this -> setData ([
'category' ,
$categoryId ,
$this -> getInput ( 'categoryAddTitle' , helper :: FILTER_STRING_SHORT , true )
]);
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/category' ,
'notification' => helper :: translate ( 'Catégorie créée' ),
'state' => true
]);
}
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Ajouter une catégorie' ),
'view' => 'categoryAdd'
]);
}
public function categoryDelete ()
{
2023-10-07 18:30:43 +02:00
// Accès refusé
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
$categories = helper :: arrayColumn ( $this -> getData ([ 'course' ]), 'category' , 'SORT_ASC' );
$courseId = $this -> getUrl ( 2 );
$message = helper :: translate ( 'Une catégorie affectée ne peut pas être effacée' );
$state = false ;
if ( in_array ( $courseId , $categories ) === false ) {
$this -> deleteData ([ 'category' , $this -> getUrl ( 2 )]);
// Valeurs en sortie
$message = helper :: translate ( 'Catégorie effacée' );
$state = true ;
}
2023-10-04 21:05:39 +02:00
// Valeurs en sortie
2023-10-07 18:30:43 +02:00
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/category' ,
'notification' => $message ,
'state' => $state
]);
2023-10-04 21:05:39 +02:00
}
}
2023-10-04 22:04:18 +02:00
public function user ()
{
2023-10-18 13:41:16 +02:00
// Cours sélectionné
$courseId = $this -> getUrl ( 2 );
2023-10-09 13:47:11 +02:00
// Liste des groupes et des profils
2023-10-09 19:10:48 +02:00
$courseGroups = $this -> getData ([ 'profil' ]);
foreach ( $courseGroups as $groupId => $groupValue ) {
2023-10-09 13:47:11 +02:00
switch ( $groupId ) {
case " -1 " :
case " 0 " :
2023-10-12 19:02:26 +02:00
break ;
2023-10-09 13:47:11 +02:00
case " 3 " :
2023-10-12 19:02:26 +02:00
self :: $courseGroups [ '30' ] = 'Administrateur' ;
2023-10-17 19:17:04 +02:00
$profils [ '30' ] = 0 ;
2023-10-09 13:47:11 +02:00
break ;
case " 1 " :
case " 2 " :
foreach ( $groupValue as $profilId => $profilValue ) {
if ( $profilId ) {
2023-10-09 19:10:48 +02:00
self :: $courseGroups [ $groupId . $profilId ] = sprintf ( helper :: translate ( 'Groupe %s - Profil %s' ), self :: $groupPublics [ $groupId ], $profilValue [ 'name' ]);
2023-10-17 19:17:04 +02:00
$profils [ $groupId . $profilId ] = 0 ;
2023-10-09 13:47:11 +02:00
}
}
}
}
2023-10-09 19:56:49 +02:00
2023-10-09 13:47:11 +02:00
// Liste alphabétique
2023-10-09 17:24:04 +02:00
self :: $alphabet = range ( 'A' , 'Z' );
$alphabet = range ( 'A' , 'Z' );
self :: $alphabet = array_combine ( $alphabet , self :: $alphabet );
2023-10-09 19:56:49 +02:00
self :: $alphabet = array_merge ([ 'all' => 'Tout' ], self :: $alphabet );
// Statistiques du cours sélectionné calcul du nombre de pages
2023-10-18 13:41:16 +02:00
$sumPages = 0 ;
$data = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
2023-10-21 11:46:58 +02:00
// Exclure les barres et les pages masquées
2023-10-19 22:53:00 +02:00
foreach ( $data [ 'page' ] as $pageId => $pageData ) {
2023-10-21 11:46:58 +02:00
if ( $pageData [ 'position' ] > 0 ) {
2023-10-19 22:53:00 +02:00
$sumPages ++ ;
2023-10-21 13:55:14 +02:00
$pages [ $pageId ] = $pageData [ 'title' ];
2023-10-18 13:41:16 +02:00
}
}
2023-10-09 19:56:49 +02:00
// Liste des inscrits dans le cours sélectionné.
2023-10-09 13:47:11 +02:00
$users = $this -> getData ([ 'enrolment' , $courseId ]);
2023-10-18 13:41:16 +02:00
2023-10-15 14:53:20 +02:00
// Tri du tableau par défaut par $userId
2023-10-04 22:04:18 +02:00
ksort ( $users );
2023-10-17 19:17:04 +02:00
2023-10-04 22:04:18 +02:00
foreach ( $users as $userId => $userValue ) {
2023-10-08 17:40:07 +02:00
$history = $userValue [ 'history' ];
2023-10-15 14:53:20 +02:00
2023-10-08 17:40:07 +02:00
$maxTime = max ( $history );
$pageId = array_search ( $maxTime , $history );
2023-10-17 22:25:56 +02:00
// Compte les rôles
$profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])] ++ ;
2023-10-09 17:24:04 +02:00
// Filtres
if ( $this -> isPost ()) {
// Groupe et profils
$group = ( string ) $this -> getData ([ 'user' , $userId , 'group' ]);
$profil = ( string ) $this -> getData ([ 'user' , $userId , 'profil' ]);
$firstName = $this -> getData ([ 'user' , $userId , 'firstname' ]);
$lastName = $this -> getData ([ 'user' , $userId , 'lastname' ]);
2023-10-09 19:56:49 +02:00
if (
$this -> getInput ( 'courseFilterGroup' , helper :: FILTER_INT ) > 0
&& $this -> getInput ( 'courseFilterGroup' , helper :: FILTER_STRING_SHORT ) !== $group . $profil
)
2023-10-09 17:24:04 +02:00
continue ;
// Première lettre du prénom
2023-10-09 19:56:49 +02:00
if (
$this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $firstName , 0 , 1 ))
)
2023-10-09 17:24:04 +02:00
continue ;
// Première lettre du nom
2023-10-09 19:56:49 +02:00
if (
$this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $lastName , 0 , 1 ))
)
2023-10-09 17:24:04 +02:00
continue ;
}
2023-10-09 19:56:49 +02:00
// Taux de parcours
$viewPages = count ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]));
2023-10-17 19:17:04 +02:00
// Construction du tableau
2023-10-04 22:04:18 +02:00
self :: $courseUsers [] = [
2023-10-21 13:43:16 +02:00
$userId ,
2023-10-04 22:04:18 +02:00
$this -> getData ([ 'user' , $userId , 'firstname' ]) . ' ' . $this -> getData ([ 'user' , $userId , 'lastname' ]),
2023-10-21 13:55:14 +02:00
$pages [ $pageId ],
2023-10-08 17:40:07 +02:00
helper :: dateUTF8 ( '%d %B %Y - %H:%M' , $maxTime ),
2023-10-18 14:04:07 +02:00
template :: button ( 'userHistory' . $userId , [
'href' => helper :: baseUrl () . 'course/userHistory/' . $courseId . '/' . $userId ,
2023-10-19 22:53:00 +02:00
'value' => round (( $viewPages * 100 ) / $sumPages , 1 ) . ' %'
]),
2023-10-07 18:30:43 +02:00
template :: button ( 'userDelete' . $userId , [
'class' => 'userDelete buttonRed' ,
2023-10-09 13:47:11 +02:00
'href' => helper :: baseUrl () . 'course/userDelete/' . $courseId . '/' . $userId ,
2023-10-07 18:30:43 +02:00
'value' => template :: ico ( 'minus' ),
'help' => 'Désinscrire'
2023-10-04 22:04:18 +02:00
])
];
2023-10-17 19:17:04 +02:00
2023-10-04 22:04:18 +02:00
}
2023-10-17 19:17:04 +02:00
// Ajoute les effectifs aux profils du sélecteur
foreach ( self :: $courseGroups as $groupId => $groupValue ) {
2023-10-17 22:25:56 +02:00
if ( $groupId === 'all' ) {
2023-10-17 19:17:04 +02:00
self :: $courseGroups [ 'all' ] = self :: $courseGroups [ 'all' ] . ' (' . array_sum ( $profils ) . ')' ;
} else {
2023-10-17 22:25:56 +02:00
self :: $courseGroups [ $groupId ] = self :: $courseGroups [ $groupId ] . ' (' . $profils [ $groupId ] . ')' ;
2023-10-17 19:17:04 +02:00
}
}
2023-10-09 17:24:04 +02:00
2023-10-04 22:04:18 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-10-18 14:04:07 +02:00
'title' => sprintf ( helper :: translate ( 'Inscriptions dans le cours %s' ), $this -> getData ([ 'course' , $courseId , 'title' ])),
2023-10-15 14:53:20 +02:00
'view' => 'user' ,
'vendor' => [
'datatables'
]
2023-10-04 22:04:18 +02:00
]);
}
public function userAdd ()
{
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Inscrire' ),
'view' => 'userAdd'
]);
}
2023-10-15 14:53:20 +02:00
/**
2023-10-07 18:30:43 +02:00
* Désinscription d ' un utilisateur
*/
public function userDelete ()
{
// Accès refusé
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
$this -> deleteData ([ 'enrolment' , $this -> getUrl ( 2 ), $this -> getUrl ( 3 )]);
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/user/' . $this -> getUrl ( 2 ),
'notification' => sprintf ( helper :: translate ( '%s est désinscrit' ), $this -> getUrl ( 3 )),
'state' => true
]);
}
}
2023-10-08 14:46:44 +02:00
/**
* Désinscription de tous les utilisateurs
*/
public function userDeleteAll ()
{
// Accès refusé
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
$this -> setData ([ 'enrolment' , $this -> getUrl ( 2 ), array ()]);
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/user/' . $this -> getUrl ( 2 ),
'notification' => helper :: translate ( 'Cours réinitialisé' ),
'state' => true
]);
}
}
2023-09-11 22:39:19 +02:00
/*
* Traitement du changement de langue
*/
public function swap ()
2023-09-26 21:26:34 +02:00
{
$courseId = $this -> getUrl ( 2 );
2023-10-02 22:18:13 +02:00
$userId = $this -> getuser ( 'id' );
2023-09-26 21:26:34 +02:00
$message = '' ;
2023-10-26 13:51:19 +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
2023-10-02 22:18:13 +02:00
$courseId === 'home'
2023-09-27 21:01:11 +02:00
) {
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
2023-09-29 03:56:12 +02:00
}
2023-10-06 18:01:40 +02:00
// l'étudiant est inscrit dans le cours ET le cours est ouvert
// ou un admin ou le prof du cours sont connectés
2023-09-27 21:01:11 +02:00
elseif (
2023-10-02 22:18:13 +02:00
$this -> courseIsUserEnroled ( $courseId )
2023-09-29 03:56:12 +02:00
&& $this -> courseIsAvailable ( $courseId )
2023-09-26 21:26:34 +02:00
) {
2023-10-01 20:59:48 +02:00
// Récupérer la dernière page visitée par cet utilisateur si elle existe
2023-10-09 20:30:17 +02:00
if ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]))
$maxTime = max ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]));
if ( is_int ( $maxTime )) {
2023-10-26 13:51:19 +02:00
$redirect = helper :: baseUrl () . array_search ( $maxTime , $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]));
2023-10-02 22:09:33 +02:00
} else {
2023-10-02 22:18:13 +02:00
// Sinon la page d'accueil par défaut du module
2023-10-26 13:51:19 +02:00
$redirect = helper :: baseUrl () . $this -> getData ([ 'course' , $courseId , 'homePageId' ]);
2023-10-01 20:22:45 +02:00
}
2023-10-02 22:43:38 +02:00
if ( $this -> getData ([ 'course' , $courseId , 'access' ]) === self :: COURSE_ACCESS_DATE ) {
2023-10-03 16:38:31 +02:00
$to = helper :: dateUTF8 ( '%d %B %Y' , $this -> getData ([ 'course' , $courseId , 'closingDate' ]), self :: $i18nUI ) . helper :: translate ( ' à ' ) . helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'course' , $courseId , 'closingDate' ]), self :: $i18nUI );
2023-10-02 22:43:38 +02:00
$message = sprintf ( helper :: translate ( 'Ce cours ferme le %s' ), $to );
} else {
2023-10-19 14:35:12 +02:00
$message = sprintf ( helper :: translate ( 'Bienvenue dans le cours %s' ), $this -> getData ([ 'course' , $courseId , 'title' ]));
2023-10-02 22:43:38 +02:00
}
2023-10-04 17:57:07 +02:00
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
2023-09-26 21:26:34 +02:00
}
// 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 ) {
2023-10-03 16:38:31 +02:00
$from = helper :: dateUTF8 ( '%d %B %Y' , $this -> getData ([ 'course' , $courseId , 'openingDate' ]), self :: $i18nUI ) . helper :: translate ( ' à ' ) . helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'course' , $courseId , 'openingDate' ]), self :: $i18nUI );
$to = helper :: dateUTF8 ( '%d %B %Y' , $this -> getData ([ 'course' , $courseId , 'closingDate' ]), self :: $i18nUI ) . helper :: translate ( ' à ' ) . helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'course' , $courseId , 'closingDate' ]), self :: $i18nUI );
2023-09-26 21:26:34 +02:00
$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 :
2023-10-26 13:51:19 +02:00
//L'étudiant doit disposer d'un compte
if ( $this -> getUser ( 'id' )) {
$redirect = helper :: baseUrl () . 'course/suscribe/' . $courseId ;
} else {
$message = helper :: translate ( 'Vous devez disposer d\'un compte pour accéder à ce cours ' );
$state = false ;
}
2023-10-06 18:01:40 +02:00
break ;
2023-09-29 04:20:09 +02:00
case self :: COURSE_ENROLMENT_SELF_KEY :
2023-10-06 18:01:40 +02:00
//L'étudiant doit disposer d'un compte
2023-09-29 04:20:09 +02:00
if ( $this -> getUser ( 'id' )) {
2023-10-26 13:51:19 +02:00
$redirect = helper :: baseUrl () . 'course/suscribe/' . $courseId ;
2023-09-29 04:20:09 +02:00
} else {
2023-10-26 13:51:19 +02:00
$message = helper :: translate ( 'Vous devez disposer d\'un compte et d\'une clé pour accéder à ce cours ' );
2023-09-29 04:49:13 +02:00
$state = false ;
2023-09-29 04:20:09 +02:00
}
break ;
// Par le prof
2023-10-06 18:01:40 +02:00
/*
2023-09-29 04:20:09 +02:00
case self :: COURSE_ENROLMENT_MANUAL :
2023-10-01 20:22:45 +02:00
$message = helper :: translate ( 'L\'enseignant ne vous a pas inscrit dans ce cours !' );
2023-09-29 04:20:09 +02:00
$state = false ;
break ;
default :
2023-10-06 18:01:40 +02:00
*/
2023-09-29 04:20:09 +02:00
}
}
2023-09-26 21:26:34 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => $redirect ,
'notification' => helper :: translate ( $message ),
'state' => $state ,
]);
}
2023-10-18 13:41:16 +02:00
/**
* Liste les pages consultées par un utilisateur
*/
public function userHistory ()
{
$courseId = $this -> getUrl ( 2 );
$userId = $this -> getUrl ( 3 );
2023-10-18 14:04:07 +02:00
$history = $this -> getData ([ 'enrolment' , $courseId , $userId ]);
2023-10-21 12:06:28 +02:00
$data = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
2023-10-24 15:13:30 +02:00
$data = $data [ 'page' ];
2023-10-21 12:06:28 +02:00
// Exclure les barres et les pages masquées
$count = 0 ;
foreach ( $data as $pageId => $pageData ) {
if ( $pageData [ 'position' ] > 0 ) {
$count ++ ;
$pages [ $pageId ] = [
'number' => $count ,
'title' => $pageData [ 'title' ],
];
}
}
2023-10-21 11:46:58 +02:00
2023-10-18 14:04:07 +02:00
foreach ( $history [ 'history' ] as $pageId => $time ) {
2023-10-18 13:41:16 +02:00
self :: $userHistory [ $pageId ] = [
2023-10-21 12:06:28 +02:00
$pages [ $pageId ][ 'number' ],
2023-10-18 14:04:07 +02:00
helper :: dateUTF8 ( '%d %B %Y - %H:%M:%S' , $time ),
2023-10-21 11:46:58 +02:00
$pages [ $pageId ][ 'title' ],
2023-10-18 14:04:07 +02:00
];
2023-10-18 13:41:16 +02:00
}
// Valeurs en sortie
$this -> addOutput ([
2023-10-18 14:04:07 +02:00
'title' => helper :: translate ( 'Historique ' ) . $this -> getData ([ 'user' , $userId , 'firstname' ]) . ' ' . $this -> getData ([ 'user' , $userId , 'lastname' ]),
2023-10-18 13:41:16 +02:00
'view' => 'userHistory' ,
'vendor' => [
'datatables'
]
]);
}
2023-09-26 21:26:34 +02:00
// Génération du message d'inscription
2023-10-26 13:51:19 +02:00
public function suscribe ()
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 );
2023-10-06 21:24:50 +02:00
// Stocker la sélection
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
2023-10-17 11:49:28 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl ()
]);
2023-09-25 21:18:06 +02:00
break ;
case self :: COURSE_ENROLMENT_SELF_KEY :
2023-10-17 12:07:15 +02:00
if ( $this -> getInput ( 'courseSwapEnrolmentKey' , helper :: FILTER_PASSWORD , true ) === $this -> getData ([ 'course' , $courseId , 'enrolmentKey' ])) {
2023-09-25 21:18:06 +02:00
$this -> courseEnrolUser ( $courseId , $userId );
2023-10-06 21:24:50 +02:00
// Stocker la sélection
$_SESSION [ 'ZWII_SITE_CONTENT' ] = $courseId ;
2023-10-17 11:49:28 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl ()
]);
2023-10-17 11:21:35 +02:00
} else {
// Valeurs en sortie
$this -> addOutput ([
2023-10-26 13:51:19 +02:00
'redirect' => helper :: baseUrl ( ! helper :: checkRewrite ()) . 'course/suscribe/' . $courseId ,
2023-10-17 11:21:35 +02:00
'state' => false ,
'notification' => 'La clé est incorrecte'
]);
2023-09-25 21:18:06 +02:00
}
break ;
}
}
}
// L'étudiant est-il inscrit
2023-10-06 21:24:50 +02:00
self :: $swapMessage [ 'submitLabel' ] = helper :: translate ( 'M\'inscrire' );
2023-09-25 21:18:06 +02:00
self :: $swapMessage [ 'enrolmentMessage' ] = '' ;
self :: $swapMessage [ 'enrolmentKey' ] = '' ;
if ( $this -> courseIsUserEnroled ( $courseId ) === false ) {
switch ( $this -> getData ([ 'course' , $courseId , 'enrolment' ])) {
case self :: COURSE_ENROLMENT_SELF :
2023-10-06 21:24:50 +02:00
if ( $userId == '' ) {
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Connectez-vous pour accéder à ce cours.' );
self :: $swapMessage [ 'submitLabel' ] = helper :: translate ( 'Connexion' );
}
2023-09-25 21:18:06 +02:00
break ;
case self :: COURSE_ENROLMENT_SELF_KEY :
2023-10-06 21:24:50 +02:00
if ( $userId == '' ) {
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Connectez-vous pour accéder à ce cours.' );
self :: $swapMessage [ 'submitLabel' ] = helper :: translate ( 'Connexion' );
} else {
2023-09-25 21:18:06 +02:00
self :: $swapMessage [ 'enrolmentKey' ] = template :: text ( 'courseSwapEnrolmentKey' , [
'label' => helper :: translate ( 'Clé d\'inscription' ),
]);
}
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 ([
2023-10-19 14:35:12 +02:00
'title' => sprintf ( helper :: translate ( 'Accéder au cours %s' ), $this -> getData ([ 'course' , $this -> getUrl ( 2 ), 'title' ])),
2023-10-19 17:23:34 +02:00
'view' => 'suscribe' ,
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-10-19 22:53:00 +02:00
public function unsuscribe ()
{
2023-10-24 15:13:30 +02:00
// Désincription du cours ouvert ou du cours sélectionné
$courseId = $this -> getUrl ( 2 ) ? $this -> getUrl ( 2 ) : self :: $siteContent ;
// home n'est pas un cours dans lequel on peut se désincrire
2023-10-26 13:51:19 +02:00
if (
$courseId !== 'home'
&& array_key_exists ( $courseId , $this -> getData ([ 'course' ]))
2023-10-24 15:13:30 +02:00
) {
$userId = $this -> getUser ( 'id' );
$this -> deleteData ([ 'enrolment' , $courseId , $userId ]);
$_SESSION [ 'ZWII_SITE_CONTENT' ] = 'home' ;
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl (),
'notification' => helper :: translate ( 'Désinscription' ),
'state' => true ,
]);
2023-10-26 13:51:19 +02:00
2023-10-24 15:13:30 +02:00
}
2023-10-19 22:53:00 +02:00
}
2023-10-18 13:41:16 +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-10-18 13:41:16 +02:00
private 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-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
{
2023-10-01 21:44:01 +02:00
// L'accès à l'accueil est toujours autorisé
2023-09-25 21:18:06 +02:00
if ( $courseId === 'home' ) {
return true ;
}
2023-10-02 22:18:13 +02:00
// Si un utilisateur connecté est admin aou auteur, c'est autorisé
if (
$this -> getUser ( 'password' ) === $this -> getInput ( 'ZWII_USER_PASSWORD' ) &&
$this -> getUser ( 'group' ) === self :: GROUP_ADMIN || $this -> getUser ( 'id' ) === $this -> getData ([ 'user' , $courseId , 'author' ])
) {
return true ;
}
2023-10-01 21:44:01 +02:00
// Retourne le statut du cours dans les autres cas
2023-09-25 21:18:06 +02:00
$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-10-17 11:21:35 +02:00
private function countPages ( $array )
{
2023-10-15 22:34:56 +02:00
$count = 0 ;
foreach ( $array as $key => $value ) {
$count ++ ; // Incrémente le compteur pour chaque clé associative trouvée
if ( is_array ( $value )) {
$count += $this -> countPages ( $value ); // Appelle récursivement la fonction si la valeur est un tableau
}
}
return $count ;
}
2023-09-21 15:34:03 +02:00
2023-10-18 13:41:16 +02:00
private function courseEnrolUser ( $courseId , $userId )
{
$this -> setData ([
'enrolment' ,
$courseId ,
$userId ,
[
'history' => [],
]
]);
}
2023-09-08 10:12:23 +02:00
}