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 >
2024-01-14 19:31:22 +01:00
* @ copyright Copyright ( C ) 2018 - 2024 , Frédéric Tempez
2023-09-08 10:12:23 +02:00
* @ 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-11-19 21:07:22 +01:00
'index' => self :: GROUP_EDITOR ,
'edit' => self :: GROUP_EDITOR ,
2024-01-14 19:30:14 +01:00
'manage' => self :: GROUP_EDITOR ,
2024-02-13 11:22:49 +01:00
'users' => self :: GROUP_EDITOR , // fait
2023-11-21 19:42:46 +01:00
'usersAdd' => self :: GROUP_EDITOR ,
'usersDelete' => self :: GROUP_EDITOR ,
2024-02-13 11:22:49 +01:00
'usersHistoryExport' => self :: GROUP_EDITOR , //fait
'userDelete' => self :: GROUP_EDITOR ,
2023-11-19 21:07:22 +01:00
'userHistory' => self :: GROUP_EDITOR ,
'userHistoryExport' => self :: GROUP_EDITOR ,
2024-01-04 16:43:45 +01:00
'backup' => self :: GROUP_EDITOR ,
'restore' => self :: GROUP_EDITOR ,
2024-02-12 13:14:02 +01:00
'clone' => self :: GROUP_ADMIN ,
2024-02-13 11:22:49 +01:00
'add' => self :: GROUP_ADMIN ,
2024-02-12 13:14:02 +01:00
'delete' => self :: GROUP_ADMIN ,
'category' => self :: GROUP_ADMIN ,
'categoryAdd' => self :: GROUP_ADMIN ,
'categoryEdit' => self :: GROUP_ADMIN ,
'categoryDelete' => 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-11-25 14:36:49 +01:00
self :: COURSE_ENROLMENT_MANDATORY => 'Imposée'
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 = [];
2024-02-12 17:21:37 +01:00
public static $userGraph = [];
2023-12-09 23:35:21 +01:00
public static $userStat = [];
2023-09-08 10:12:23 +02:00
public function index ()
{
2024-02-13 10:28:30 +01:00
// Tableau à transmettre à la fvue
2023-11-21 11:00:02 +01:00
self :: $courses = array ();
2024-02-13 10:28:30 +01:00
2023-11-21 11:00:02 +01:00
if (
$this -> getUser ( 'id' )
&& $this -> getUser ( 'group' )
) {
2024-02-13 10:28:30 +01:00
foreach ( $this -> getData ([ 'course' ]) as $courseId => $courseValue ) {
2024-01-21 12:02:26 +01:00
/**
* Filtres :
* Groupes acceptés :
* admin : tous les espaces
2024-02-12 13:14:02 +01:00
* editor : gère son espace son espace dans lequel il est inscrit
2024-01-21 12:02:26 +01:00
*/
2024-02-12 17:21:37 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId )
2024-01-21 12:02:26 +01:00
) {
2024-02-12 13:14:02 +01:00
$author = $this -> getData ([ 'course' , $courseId , 'author' ])
? sprintf ( '%s %s' , $this -> getData ([ 'user' , $this -> getData ([ 'course' , $courseId , 'author' ]), 'firstname' ]), $this -> getData ([ 'user' , $this -> getData ([ 'course' , $courseId , 'author' ]), 'lastname' ]))
: '' ;
$categorieUrl = helper :: baseUrl () . 'course/swap/' . $courseId ;
$info = sprintf ( '<strong>%s<br /></strong>Auteur : %s<br />Id : <a href="%s" target="_blank">%s<br />' , $this -> getData ([ 'course' , $courseId , 'title' ]), $author , $categorieUrl , $courseId );
$enrolment = sprintf (
'Accès : %s<br />Inscription : %s<br />' ,
self :: $courseAccess [ $this -> getData ([ 'course' , $courseId , 'access' ])],
self :: $courseEnrolment [ $this -> getData ([ 'course' , $courseId , 'enrolment' ])]
);
self :: $courses [] = [
$info ,
$this -> getData ([ 'course' , $courseId , 'description' ]),
$enrolment ,
template :: button ( 'categoryUser' . $courseId , [
'href' => helper :: baseUrl () . 'course/manage/' . $courseId ,
'value' => template :: ico ( 'eye' ),
'help' => 'Gérer'
])
];
}
2023-11-19 21:07:22 +01:00
}
2023-09-12 22:16:25 +02:00
}
2023-09-29 04:49:13 +02:00
2023-09-08 22:09:25 +02:00
// Valeurs en sortie
$this -> addOutput ([
2024-02-13 10:28:30 +01:00
'title' => helper :: translate ( 'Gestionnaire d\'espaces' ),
2023-12-09 17:58:14 +01:00
'view' => 'index' ,
'vendor' => [
'datatables'
]
2023-09-08 22:09:25 +02:00
]);
}
2023-09-11 22:39:19 +02:00
/**
2023-11-15 18:06:49 +01:00
* Ajoute un nouveau contenu
2023-09-11 22:39:19 +02:00
*/
2023-09-08 22:09:25 +02:00
public function add ()
{
2024-02-12 13:14:02 +01:00
// Accès limité aux admins
if (
$this -> getUser ( 'group' ) !== self :: GROUP_ADMIN
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-09-08 22:09:25 +02:00
// Soumission du formulaire
if (
$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-09-30 13:35:20 +02:00
'author' => $this -> getInput ( 'courseAddAuthor' ),
2023-10-04 17:58:58 +02:00
'homePageId' => 'accueil' ,
2023-10-28 23:18:07 +02:00
'category' => $this -> getInput ( 'courseAddCategorie' ),
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-10-27 21:40:53 +02:00
'openingDate' => $this -> getInput ( 'courseAddOpeningDate' , helper :: FILTER_DATETIME ),
'closingDate' => $this -> getInput ( 'courseAddClosingDate' , 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-11-18 16:14:19 +01:00
'limitEnrolment' => $this -> getInput ( 'courseAddEnrolmentLimit' , helper :: FILTER_BOOLEAN ),
'limitEnrolmentDate' => $this -> getInput ( 'courseAddEnrolmentLimitDate' , helper :: FILTER_DATETIME ),
2023-09-08 22:09:25 +02:00
]
]);
2023-09-08 10:12:23 +02:00
2023-12-14 13:44:24 +01:00
// Dossier du gestionnaire de fichier
mkdir ( self :: FILE_DIR . 'source/' . $courseId );
2023-10-27 21:40:53 +02:00
// Copie du thème
$sourceId = $this -> getInput ( 'courseAddTheme' );
copy ( self :: DATA_DIR . $sourceId . '/theme.json' , self :: DATA_DIR . $courseId . '/theme.json' );
copy ( self :: DATA_DIR . $sourceId . '/theme.css' , self :: DATA_DIR . $courseId . '/theme.css' );
2023-09-11 22:39:19 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
2023-12-07 10:40:47 +01:00
'notification' => helper :: translate ( 'Espace créé' ),
2023-09-11 22:39:19 +02:00
'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-11-15 18:06:49 +01:00
// Liste des catégories de contenu
2023-09-29 04:49:13 +02:00
self :: $courseCategories = $this -> getData ([ 'category' ]);
2023-11-15 18:06:49 +01:00
// Liste des contenus disponibles pour la copie du thème
2023-10-27 21:40:53 +02:00
self :: $courses = $this -> getData ([ 'course' ]);
2023-11-10 08:59:07 +01:00
self :: $courses = helper :: arrayColumn ( self :: $courses , 'title' , 'SORT_ASC' );
self :: $courses = array_merge ([ 'home' => 'Accueil de la plate-forme' ], self :: $courses );
2023-10-27 21:40:53 +02:00
2023-09-08 22:09:25 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-12-07 10:40:47 +01:00
'title' => helper :: translate ( 'Ajouter un espace' ),
2023-09-08 22:09:25 +02:00
'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
/**
2024-01-14 19:30:14 +01:00
* Edite un espace
2023-09-12 22:16:25 +02:00
*/
public function edit ()
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
2024-01-21 12:02:26 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2024-01-21 12:02:26 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-09-12 22:16:25 +02:00
// Soumission du formulaire
if (
2024-02-12 13:14:02 +01:00
//$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
2023-09-12 22:16:25 +02:00
$this -> isPost ()
) {
2024-02-12 13:14:02 +01:00
2023-09-12 22:16:25 +02:00
$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' ),
2023-10-28 23:18:07 +02:00
'category' => $this -> getInput ( 'courseEditCategorie' ),
2024-01-21 11:28:38 +01:00
'description' => $this -> getInput ( 'courseEditDescription' , helper :: FILTER_STRING_LONG , 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' ),
2023-11-18 16:14:19 +01:00
'limitEnrolment' => $this -> getInput ( 'courseEditEnrolmentLimit' , helper :: FILTER_BOOLEAN ),
'limitEnrolmentDate' => $this -> getInput ( 'courseEditEnrolmentLimitDate' , helper :: FILTER_DATETIME ),
2023-09-12 22:16:25 +02:00
]
]);
// Valeurs en sortie
$this -> addOutput ([
2024-01-14 19:30:14 +01:00
'redirect' => helper :: baseUrl () . 'course/manage/' . $this -> getUrl ( 2 ),
2023-12-07 10:40:47 +01:00
'notification' => helper :: translate ( 'Espace modifié' ),
2023-09-12 22:16:25 +02:00
'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
2023-11-15 18:06:49 +01:00
// Liste des catégories de contenu
2023-09-29 04:49:13 +02:00
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 ([
2024-01-21 11:28:38 +01:00
'title' => sprintf ( '%s id : %s' , helper :: translate ( 'Éditer l\'espace' ), $this -> getUrl ( 2 )),
2023-09-12 22:16:25 +02:00
'view' => 'edit'
]);
}
2024-01-14 19:30:14 +01:00
/**
* Affiche un contenu et pointe vers les utilitaires
*/
public function manage ()
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
2024-01-21 12:02:26 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2024-01-21 12:02:26 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2024-01-14 20:56:23 +01:00
// 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 " ];
}
}
// Liste des catégories de contenu
self :: $courseCategories = $this -> getData ([ 'category' ]);
// Liste des pages disponibles
$this -> initDB ( 'page' , $this -> getUrl ( 2 ));
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 ]);
}
}
2024-01-14 19:30:14 +01:00
// Valeurs en sortie
$this -> addOutput ([
2024-01-21 11:28:38 +01:00
'title' => sprintf ( '%s id : %s' , helper :: translate ( 'Gérer l\'espace' ), $this -> getUrl ( 2 )),
2024-01-14 19:30:14 +01:00
'view' => 'manage'
]);
}
2024-01-14 20:56:23 +01:00
/**
* Duplique un cours et l 'affiche dans l' éditeur
*/
2024-01-18 22:16:59 +01:00
public function clone ()
2024-01-14 20:56:23 +01:00
{
2024-01-21 12:02:26 +01:00
2024-02-12 13:14:02 +01:00
// Cours à dupliquer
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
2024-01-21 12:02:26 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
2024-01-21 12:02:26 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
2024-02-12 13:14:02 +01:00
} else {
// Id du nouveau cours
$target = uniqid ();
2024-01-14 20:56:23 +01:00
2024-02-12 13:14:02 +01:00
// Créer la structure de données
mkdir ( self :: DATA_DIR . $target );
2024-01-14 20:56:23 +01:00
2024-02-12 13:14:02 +01:00
$this -> copyDir ( self :: DATA_DIR . $courseId , self :: DATA_DIR . $target );
2024-01-14 20:56:23 +01:00
2024-02-12 13:14:02 +01:00
$this -> setData ([ 'course' , $target , $this -> getData ([ 'course' , $courseId ])]);
2024-01-14 20:56:23 +01:00
2024-02-12 13:14:02 +01:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'notification' => helper :: translate ( 'Espace dupliqué' ),
'state' => true
]);
}
2024-01-14 20:56:23 +01:00
}
2024-01-14 19:30:14 +01:00
2023-09-29 04:28:17 +02:00
public function delete ()
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
2023-10-04 17:57:07 +02:00
$courseId = $this -> getUrl ( 2 );
2024-02-12 13:14:02 +01:00
2023-09-29 04:28:17 +02:00
if (
2024-02-12 13:14:02 +01:00
// Accès limité aux admins
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
// Le contenu n'existe pas
|| $this -> getData ([ 'course' , $courseId ]) === null
2023-09-29 04:28:17 +02:00
) {
// 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 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-12-14 13:44:24 +01:00
}
// Dossier du gestionnaire de fichier
2024-01-04 16:24:00 +01:00
if ( is_dir ( self :: FILE_DIR . 'source/' . $courseId )) {
2023-12-14 13:44:24 +01:00
$this -> deleteDir ( self :: FILE_DIR . 'source/' . $courseId );
2023-10-04 17:57:07 +02:00
}
2023-09-29 04:28:17 +02:00
// Valeurs en sortie
$this -> addOutput ([
2024-01-14 20:56:23 +01:00
'redirect' => helper :: baseUrl () . 'course' ,
2023-12-07 10:40:47 +01:00
'notification' => $success ? helper :: translate ( 'Espace supprimé' ) : helper :: translate ( 'Erreur de suppression' ),
2024-01-14 20:56:23 +01:00
'state' => $success
2023-09-29 04:28:17 +02:00
]);
}
}
2023-09-29 04:49:13 +02:00
/**
2023-11-15 18:06:49 +01:00
* Liste les catégories d ' un contenu
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
{
2024-02-12 13:14:02 +01:00
if (
// Accès limité aux admins
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
$categories = $this -> getData ([ 'category' ]);
ksort ( $categories );
foreach ( $categories as $categoryId => $categoryTitle ) {
self :: $courseCategories [] = [
$categoryId ,
$categoryTitle ,
template :: button ( 'categoryEdit' . $categoryId , [
'href' => helper :: baseUrl () . 'course/categoryEdit/' . $categoryId ,
'value' => template :: ico ( 'pencil' ),
'help' => 'Éditer'
]),
template :: button ( 'courseDelete' . $categoryId , [
'class' => 'categoryDelete buttonRed' ,
'href' => helper :: baseUrl () . 'course/categoryDelete/' . $categoryId ,
'value' => template :: ico ( 'trash' ),
'help' => 'Supprimer'
])
];
}
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Catégories' ),
'view' => 'category'
]);
2023-09-30 09:18:08 +02:00
}
2023-09-21 15:34:03 +02:00
}
2023-10-04 21:05:39 +02:00
public function categoryAdd ()
{
if (
2024-02-12 13:14:02 +01:00
// Accès limité aux admins
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
2023-10-04 21:05:39 +02:00
) {
2024-02-12 13:14:02 +01:00
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]); // Soumission du formulaire
} elseif ( $this -> isPost ()) {
2023-10-04 21:05:39 +02:00
$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
2024-02-12 13:14:02 +01:00
]); // Valeurs en sortie
2023-10-04 21:05:39 +02:00
2024-02-12 13:14:02 +01:00
}
2023-10-04 21:05:39 +02:00
$this -> addOutput ([
'title' => helper :: translate ( 'Ajouter une catégorie' ),
'view' => 'categoryAdd'
]);
2024-02-12 13:14:02 +01:00
2023-10-04 21:05:39 +02:00
}
2023-11-08 18:06:33 +01:00
public function categoryEdit ()
{
if (
2024-02-12 13:14:02 +01:00
// Accès limité aux admins
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]); // Soumission du formulaire
} elseif (
2023-11-08 18:06:33 +01:00
$this -> isPost ()
) {
$categoryId = $this -> getUrl ( 2 );
$this -> setData ([
'category' ,
$categoryId ,
$this -> getInput ( 'categoryEditTitle' , helper :: FILTER_STRING_SHORT , true )
]);
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/category' ,
'notification' => helper :: translate ( 'Catégorie éditée' ),
'state' => true
]);
}
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Éditer une catégorie' ),
'view' => 'categoryEdit'
]);
}
2023-10-04 21:05:39 +02:00
public function categoryDelete ()
{
2023-10-07 18:30:43 +02:00
if (
2024-02-12 13:14:02 +01:00
// Accès limité aux admins
$this -> getUser ( 'group' ) !== self :: $actions [ __FUNCTION__ ]
2023-10-07 18:30:43 +02:00
) {
// 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-11-21 19:42:46 +01:00
public function users ()
2023-10-04 22:04:18 +02:00
{
2023-10-18 13:41:16 +02:00
2024-02-12 13:14:02 +01:00
$courseId = $this -> getUrl ( 2 );
// Accès limité au propriétaire, admin ou éditeurs isncrits
2024-01-21 12:02:26 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2024-01-21 12:02:26 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-11-15 18:06:49 +01:00
// Contenu sélectionné
2023-10-18 13:41:16 +02:00
$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 );
2023-12-09 17:20:40 +01:00
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
2023-10-18 13:41:16 +02:00
$sumPages = 0 ;
2023-12-09 17:20:40 +01:00
$pages = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
2024-01-04 16:24:00 +01:00
$pages = $pages [ 'page' ];
2023-12-09 17:20:40 +01:00
foreach ( $pages 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-18 13:41:16 +02:00
}
}
2023-10-09 19:56:49 +02:00
2023-11-15 18:06:49 +01:00
// Liste des inscrits dans le contenu sélectionné.
2023-10-09 13:47:11 +02:00
$users = $this -> getData ([ 'enrolment' , $courseId ]);
2023-10-18 13:41:16 +02:00
2024-01-18 22:16:59 +01:00
if ( is_array ( $users )) {
// Tri du tableau par défaut par $userId
ksort ( $users );
foreach ( $users as $userId => $userValue ) {
2023-10-17 19:17:04 +02:00
2024-01-18 22:16:59 +01:00
// Date et heure de la dernière page vue
// Compatibilité anciennes versions
if (
$this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ]) === null
or $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ]) === null
) {
if ( ! empty ( $userValue [ 'history' ])) {
$maxTime = max ( $userValue [ 'history' ]);
$lastPageId = array_search ( $maxTime , $userValue [ 'history' ]);
$this -> setData ([ 'enrolment' , $courseId , $userId , 'lastPageView' , $lastPageId ]);
$this -> setData ([ 'enrolment' , $courseId , $userId , 'datePageView' , $maxTime ]);
}
2023-12-08 23:04:14 +01:00
}
2023-12-09 13:25:18 +01:00
2023-10-17 22:25:56 +02:00
2024-01-18 22:16:59 +01:00
// Compte les rôles valides
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
$profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])] ++ ;
}
2023-10-09 19:56:49 +02:00
2024-01-18 22:16:59 +01: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' ]);
if (
$this -> getInput ( 'courseFilterGroup' , helper :: FILTER_INT ) > 0
&& $this -> getInput ( 'courseFilterGroup' , helper :: FILTER_STRING_SHORT ) !== $group . $profil
)
continue ;
// Première lettre du prénom
if (
$this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $firstName , 0 , 1 ))
)
continue ;
// Première lettre du nom
if (
$this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $lastName , 0 , 1 ))
)
continue ;
}
2024-01-03 16:40:23 +01:00
2024-01-18 22:16:59 +01:00
// Progression
$viewPages = $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]) !== null ?
count ( array_keys ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]))) :
0 ;
// Construction du tableau
self :: $courseUsers [] = [
2024-02-11 17:53:56 +01:00
//$userId,
2024-01-18 22:16:59 +01:00
$this -> getData ([ 'user' , $userId , 'firstname' ]) . ' ' . $this -> getData ([ 'user' , $userId , 'lastname' ]),
isset ( $pages [ $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])][ 'title' ])
? $pages [ $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])][ 'title' ]
: '' ,
$this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])
2024-02-08 19:39:51 +01:00
? helper :: dateUTF8 ( '%d/%m/%Y' , $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ]))
: '' ,
$this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])
? helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ]))
2024-01-18 22:16:59 +01:00
: '' ,
$this -> getData ([ 'user' , $userId , 'tags' ]),
template :: button ( 'userHistory' . $userId , [
'href' => helper :: baseUrl () . 'course/userHistory/' . $courseId . '/' . $userId ,
2024-01-30 18:51:19 +01:00
'value' => ! empty ( $userValue [ 'history' ]) ? min ( round (( $viewPages * 100 ) / $sumPages , 1 ), 100 ) . ' %' : '0%' ,
2024-01-18 22:16:59 +01:00
'disable' => empty ( $userValue [ 'history' ])
]),
template :: button ( 'userDelete' . $userId , [
'class' => 'userDelete buttonRed' ,
'href' => helper :: baseUrl () . 'course/userDelete/' . $courseId . '/' . $userId ,
'value' => template :: ico ( 'user' ),
'help' => 'Désinscrire'
])
];
2023-10-17 19:17:04 +02:00
2024-01-18 22:16:59 +01: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-11-30 10:16:42 +01:00
'title' => sprintf ( helper :: translate ( 'Participants %s' ), $this -> getData ([ 'course' , $courseId , 'title' ])),
2023-11-21 19:42:46 +01:00
'view' => 'users' ,
2023-12-09 17:58:14 +01:00
'vendor' => [
'datatables'
]
2023-10-04 22:04:18 +02:00
]);
}
2023-11-21 19:42:46 +01:00
public function usersAdd ()
2023-10-04 22:04:18 +02:00
{
2023-11-23 11:25:42 +01:00
2024-02-12 13:14:02 +01:00
// Contenu sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité au propriétaire ou éditeurs inscrits ou admin
2024-01-21 12:02:26 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2024-01-21 12:02:26 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-11-23 11:25:42 +01:00
// Inscription des utilisateurs cochés
if (
isset ( $_POST [ 'courseUsersAddSubmit' ])
) {
foreach ( $_POST as $keyPost => $valuePost ) {
// Exclure les variables post qui ne sont pas des userId et ne traiter que les non inscrits
2023-11-23 13:59:27 +01:00
if (
$this -> getData ([ 'user' , $keyPost ]) !== null
2023-11-23 11:25:42 +01:00
&& $this -> getData ([ 'enrolment' , $courseId , $keyPost ]) === null
) {
$this -> setData ([ 'enrolment' , $courseId , $keyPost , 'history' , array ()]);
2023-11-23 08:47:00 +01:00
}
}
}
2023-11-21 12:46:19 +01:00
// Liste des groupes et des profils
$courseGroups = $this -> getData ([ 'profil' ]);
foreach ( $courseGroups as $groupId => $groupValue ) {
switch ( $groupId ) {
case " -1 " :
case " 0 " :
break ;
case " 3 " :
self :: $courseGroups [ '30' ] = 'Administrateur' ;
$profils [ '30' ] = 0 ;
break ;
case " 1 " :
case " 2 " :
foreach ( $groupValue as $profilId => $profilValue ) {
if ( $profilId ) {
self :: $courseGroups [ $groupId . $profilId ] = sprintf ( helper :: translate ( 'Groupe %s - Profil %s' ), self :: $groupPublics [ $groupId ], $profilValue [ 'name' ]);
$profils [ $groupId . $profilId ] = 0 ;
}
}
}
}
// Liste alphabétique
self :: $alphabet = range ( 'A' , 'Z' );
$alphabet = range ( 'A' , 'Z' );
self :: $alphabet = array_combine ( $alphabet , self :: $alphabet );
self :: $alphabet = array_merge ([ 'all' => 'Tout' ], self :: $alphabet );
2024-01-18 22:16:59 +01:00
// Liste des inscrits dans l'espace sélectionné afin de les supprimer de la liste des candidats
$users = $this -> getData ([ 'user' ]);
2023-11-23 11:25:42 +01:00
$suscribers = $this -> getData ([ 'enrolment' , $courseId ]);
2024-01-18 22:16:59 +01:00
if ( is_array ( $suscribers )) {
$suscribers = array_keys ( $suscribers );
$users = array_diff_key ( $users , array_flip ( $suscribers ));
2023-11-23 11:25:42 +01:00
2024-01-18 22:16:59 +01:00
}
2023-11-23 11:25:42 +01:00
// Tri du tableau par défaut par $userId
ksort ( $users );
2023-11-21 12:46:19 +01:00
foreach ( $users as $userId => $userValue ) {
2023-11-23 11:25:42 +01:00
// Compte les rôles
2023-11-30 14:26:11 +01:00
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
$profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])] ++ ;
}
2023-11-23 11:25:42 +01:00
2023-11-21 12:46:19 +01:00
// Filtres
2023-11-23 11:25:42 +01:00
if (
isset ( $_POST [ 'courseFilterGroup' ])
|| isset ( $_POST [ 'courseFilterFirstName' ])
|| isset ( $_POST [ 'courseFilterLastName' ])
) {
2023-11-23 08:47:00 +01:00
2023-11-21 12:46:19 +01:00
// 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' ]);
if (
$this -> getInput ( 'courseFilterGroup' , helper :: FILTER_INT ) > 0
&& $this -> getInput ( 'courseFilterGroup' , helper :: FILTER_STRING_SHORT ) !== $group . $profil
)
continue ;
// Première lettre du prénom
if (
$this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $firstName , 0 , 1 ))
)
continue ;
// Première lettre du nom
if (
$this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $lastName , 0 , 1 ))
)
continue ;
}
// Construction du tableau
self :: $courseUsers [] = [
2023-11-25 15:10:10 +01:00
template :: checkbox ( $userId , true , '' , [ 'class' => 'checkboxSelect' ]),
2023-11-21 12:46:19 +01:00
$userId ,
2023-11-21 19:42:46 +01:00
$this -> getData ([ 'user' , $userId , 'firstname' ]),
$this -> getData ([ 'user' , $userId , 'lastname' ]),
2023-11-30 14:12:03 +01:00
$this -> getData ([ 'user' , $userId , 'tags' ]),
2023-11-21 12:46:19 +01:00
];
}
2023-11-23 11:25:42 +01:00
// Ajoute les effectifs aux profils du sélecteur
foreach ( self :: $courseGroups as $groupId => $groupValue ) {
if ( $groupId === 'all' ) {
self :: $courseGroups [ 'all' ] = self :: $courseGroups [ 'all' ] . ' (' . array_sum ( $profils ) . ')' ;
} else {
self :: $courseGroups [ $groupId ] = self :: $courseGroups [ $groupId ] . ' (' . $profils [ $groupId ] . ')' ;
}
}
2023-10-04 22:04:18 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-11-21 12:46:19 +01:00
'title' => helper :: translate ( 'Inscription en masse' ),
2023-12-09 17:58:14 +01:00
'view' => 'usersAdd' ,
'vendor' => [
'datatables'
]
2023-10-04 22:04:18 +02:00
]);
}
2023-10-15 14:53:20 +02:00
/**
2023-10-07 18:30:43 +02:00
* Désinscription d ' un utilisateur
*/
public function userDelete ()
{
2024-02-12 13:14:02 +01:00
// Contenu sélectionné
$courseId = $this -> getUrl ( 2 );
2024-01-21 12:02:26 +01:00
2024-02-12 13:14:02 +01:00
// Accès limité au propriétaire ou admin ou éditeurs inscrits
2023-10-07 18:30:43 +02:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2023-10-07 18:30:43 +02:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
$this -> deleteData ([ 'enrolment' , $this -> getUrl ( 2 ), $this -> getUrl ( 3 )]);
// Valeurs en sortie
$this -> addOutput ([
2023-11-23 08:47:00 +01:00
'redirect' => helper :: baseUrl () . 'course/users/' . $this -> getUrl ( 2 ),
2023-10-07 18:30:43 +02:00
'notification' => sprintf ( helper :: translate ( '%s est désinscrit' ), $this -> getUrl ( 3 )),
'state' => true
]);
}
}
2024-01-21 12:02:26 +01:00
/**
2023-10-08 14:46:44 +02:00
* Désinscription de tous les utilisateurs
*/
2023-11-21 19:42:46 +01:00
public function usersDelete ()
2023-10-08 14:46:44 +02:00
{
2023-11-23 18:42:08 +01:00
// Contenu sélectionné
$courseId = $this -> getUrl ( 2 );
2024-02-12 13:14:02 +01:00
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
if (
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-11-23 18:42:08 +01:00
// Inscription des utilisateurs cochés
2023-10-08 14:46:44 +02:00
if (
2023-11-23 18:42:08 +01:00
isset ( $_POST [ 'courseUsersDeleteSubmit' ])
2023-10-08 14:46:44 +02:00
) {
2023-11-23 18:42:08 +01:00
foreach ( $_POST as $keyPost => $valuePost ) {
// Exclure les variables post qui ne sont pas des userId et ne traiter que les non inscrits
if (
$this -> getData ([ 'user' , $keyPost ]) !== null
&& $this -> getData ([ 'enrolment' , $courseId , $keyPost ]) !== null
) {
$this -> deleteData ([ 'enrolment' , $courseId , $keyPost ]);
}
}
2023-10-08 14:46:44 +02:00
}
2023-11-23 18:42:08 +01:00
// Liste des groupes et des profils
$courseGroups = $this -> getData ([ 'profil' ]);
foreach ( $courseGroups as $groupId => $groupValue ) {
switch ( $groupId ) {
case " -1 " :
case " 0 " :
break ;
case " 3 " :
self :: $courseGroups [ '30' ] = 'Administrateur' ;
$profils [ '30' ] = 0 ;
break ;
case " 1 " :
case " 2 " :
foreach ( $groupValue as $profilId => $profilValue ) {
if ( $profilId ) {
self :: $courseGroups [ $groupId . $profilId ] = sprintf ( helper :: translate ( 'Groupe %s - Profil %s' ), self :: $groupPublics [ $groupId ], $profilValue [ 'name' ]);
$profils [ $groupId . $profilId ] = 0 ;
}
}
}
}
// Liste alphabétique
self :: $alphabet = range ( 'A' , 'Z' );
$alphabet = range ( 'A' , 'Z' );
self :: $alphabet = array_combine ( $alphabet , self :: $alphabet );
self :: $alphabet = array_merge ([ 'all' => 'Tout' ], self :: $alphabet );
// Liste des inscrits dans le contenu sélectionné.
$users = $this -> getData ([ 'enrolment' , $courseId ]);
2024-01-18 22:16:59 +01:00
if ( is_array ( $users )) {
// Tri du tableau par défaut par $userId
ksort ( $users );
foreach ( $users as $userId => $userValue ) {
2023-11-23 18:42:08 +01:00
2024-01-18 22:16:59 +01:00
// Compte les rôles
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
$profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])] ++ ;
}
2023-11-23 18:42:08 +01:00
2024-01-18 22:16:59 +01:00
// Filtres
2023-11-23 18:42:08 +01:00
if (
2024-01-18 22:16:59 +01:00
isset ( $_POST [ 'courseFilterGroup' ])
|| isset ( $_POST [ 'courseFilterFirstName' ])
|| isset ( $_POST [ 'courseFilterLastName' ])
) {
2023-11-23 18:42:08 +01:00
2024-01-18 22:16:59 +01:00
// 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' ]);
if (
$this -> getInput ( 'courseFilterGroup' , helper :: FILTER_INT ) > 0
&& $this -> getInput ( 'courseFilterGroup' , helper :: FILTER_STRING_SHORT ) !== $group . $profil
)
continue ;
// Première lettre du prénom
if (
$this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterFirstName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $firstName , 0 , 1 ))
)
continue ;
// Première lettre du nom
if (
$this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== 'all'
&& $this -> getInput ( 'courseFilterLastName' , helper :: FILTER_STRING_SHORT ) !== strtoupper ( substr ( $lastName , 0 , 1 ))
)
continue ;
}
// Construction du tableau
self :: $courseUsers [] = [
template :: checkbox ( $userId , true , '' , [ 'class' => 'checkboxSelect' ]),
$userId ,
$this -> getData ([ 'user' , $userId , 'firstname' ]),
$this -> getData ([ 'user' , $userId , 'lastname' ]),
$this -> getData ([ 'user' , $userId , 'tags' ]),
];
2023-11-23 18:42:08 +01:00
2024-01-18 22:16:59 +01:00
}
2023-11-23 18:42:08 +01:00
}
// Ajoute les effectifs aux profils du sélecteur
foreach ( self :: $courseGroups as $groupId => $groupValue ) {
if ( $groupId === 'all' ) {
self :: $courseGroups [ 'all' ] = self :: $courseGroups [ 'all' ] . ' (' . array_sum ( $profils ) . ')' ;
} else {
self :: $courseGroups [ $groupId ] = self :: $courseGroups [ $groupId ] . ' (' . $profils [ $groupId ] . ')' ;
}
}
// Valeurs en sortie
$this -> addOutput ([
'title' => helper :: translate ( 'Désincription en masse' ),
2023-12-09 17:58:14 +01:00
'view' => 'usersDelete' ,
'vendor' => [
'datatables'
]
2023-11-23 18:42:08 +01:00
]);
2023-10-08 14:46:44 +02:00
}
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-12-15 22:51:05 +01:00
// pageIfd est transmis lors de l'appel de la page depuis un lien direct alors que l'espace n'est pas sélectionné.
$pageId = $this -> getUrl ( 3 );
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 (
2023-11-15 18:06:49 +01:00
// Sortir du contenu 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-11-15 18:06:49 +01:00
// l'étudiant est inscrit dans le contenu ET le contenu est ouvert
// ou un admin ou le prof du contenu 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-12-09 13:25:18 +01:00
$redirect = $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])
? helper :: baseUrl () . $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])
2023-12-15 22:51:05 +01:00
: helper :: baseUrl () . $pageId ;
2023-12-09 13:25:18 +01:00
/*
$essage = $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])
? $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])
: '' ;
*/
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-12-09 13:25:18 +01:00
$message .= sprintf ( helper :: translate ( 'Ce contenu ferme le %s' ), $to );
2023-10-02 22:43:38 +02:00
} else {
2023-12-09 13:25:18 +01:00
$message .= sprintf ( helper :: translate ( 'Bienvenue dans l\'espace %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
}
2023-11-15 18:06:49 +01:00
// Le contenu 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-12-07 10:40:47 +01:00
$message = helper :: translate ( 'Cet espace est fermé' );
2023-09-29 03:56:12 +02:00
$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-12-07 10:40:47 +01:00
$message = sprintf ( helper :: translate ( 'Cet espace ouvre le <br>%s <br> et ferme le %s' ), $from , $to );
2023-09-26 21:26:34 +02:00
}
}
2023-11-15 18:06:49 +01:00
// le contenu est ouvert, l'étudiant n'est pas inscrit, l'accès au contenu est anonyme
2023-09-29 04:20:09 +02:00
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 ;
2023-12-15 22:51:05 +01:00
// Accès direct à la page
$redirect = helper :: baseUrl () . $pageId ;
2023-09-29 04:20:09 +02:00
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 ;
2023-11-10 08:59:07 +01:00
} else {
2023-12-07 10:40:47 +01:00
$message = helper :: translate ( 'Vous devez disposer d\'un compte pour accéder à cet espace' );
2023-10-26 13:51:19 +02:00
$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-12-07 10:40:47 +01:00
$message = helper :: translate ( 'Vous devez disposer d\'un compte et d\'une clé pour accéder à cet espace' );
2023-09-29 04:49:13 +02:00
$state = false ;
2023-09-29 04:20:09 +02:00
}
break ;
// Par le prof
2023-11-25 14:36:49 +01:00
case self :: COURSE_ENROLMENT_MANDATORY :
$message = helper :: translate ( 'L\'enseignant doit vous inscrire' );
2023-09-29 04:20:09 +02:00
$state = false ;
break ;
default :
}
}
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 ()
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
2023-10-18 13:41:16 +02:00
$courseId = $this -> getUrl ( 2 );
2024-02-12 13:14:02 +01:00
// Accès limité au propriétaire ou éditeurs inscrits ou admin
if (
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-10-18 13:41:16 +02:00
$userId = $this -> getUrl ( 3 );
2024-02-09 15:38:32 +01:00
$h = $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]);
// Inversion des clés et des valeurs
$history = array ();
foreach ( $h as $key => $values ) {
foreach ( $values as $value ) {
$history [ $value ] = $key ;
}
}
ksort ( $history );
2023-12-09 17:20:40 +01:00
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
2024-02-09 15:38:32 +01:00
$p = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
foreach ( $p [ 'page' ] as $pageId => $pageData ) {
2023-10-21 12:06:28 +02:00
if ( $pageData [ 'position' ] > 0 ) {
$pages [ $pageId ] = [
'title' => $pageData [ 'title' ],
];
}
}
2024-01-04 16:24:00 +01:00
2023-12-09 23:35:21 +01:00
$floorTime = 99999999999 ;
$topTime = 0 ;
2024-02-09 15:38:32 +01:00
$lastView = 0 ;
2023-10-21 11:46:58 +02:00
2024-02-09 15:38:32 +01:00
foreach ( $history as $time => $pageId ) {
if ( isset ( $pages [ $pageId ][ 'title' ])) {
$lastView = ( $lastView === 0 ) ? $time : $lastView ;
$diff = $time - $lastView ;
self :: $userHistory [] = [
html_entity_decode ( $pages [ $pageId ][ 'title' ]),
$time ,
( $diff < 1800 ) ? sprintf ( " %d' %d'' " , floor ( $diff / 60 ), $diff % 60 ) : " Non significatif " ,
];
2024-02-12 17:21:37 +01:00
if ( $diff < 1800 ) {
self :: $userGraph [] = [
2024-02-13 07:44:07 +01:00
helper :: dateUTF8 ( '%Y-%m-%d %H:%M:%S' , $time ),
2024-02-12 17:21:37 +01:00
$diff ,
2024-02-13 08:43:09 +01:00
html_entity_decode ( $pages [ $pageId ][ 'title' ]) . ' (' . helper :: dateUTF8 ( '%M\'%S"' , $diff ) . ')'
2024-02-12 17:21:37 +01:00
];
}
2024-02-09 15:38:32 +01:00
$lastView = $time ;
$floorTime = isset ( $floorTime ) && $floorTime < $time ? $floorTime : $time ;
$topTime = isset ( $topTime ) && $topTime > $time ? $topTime : $time ;
2023-12-09 13:25:18 +01:00
}
2023-10-18 13:41:16 +02:00
}
2024-02-09 15:38:32 +01:00
// Décale les temps de consultation
for ( $i = 0 ; $i < count ( self :: $userHistory ) - 1 ; $i ++ ) {
self :: $userHistory [ $i ][ 2 ] = self :: $userHistory [ $i + 1 ][ 2 ];
}
2024-02-13 08:43:09 +01:00
// Décale les temps de consultation
for ( $i = 0 ; $i < count ( self :: $userGraph ) - 1 ; $i ++ ) {
self :: $userHistory [ $i ][ 1 ] = self :: $userHistory [ $i + 1 ][ 1 ];
}
2024-02-09 15:38:32 +01:00
// Formate le timestamp
array_walk ( self :: $userHistory , function ( & $item ) {
$item [ 1 ] = helper :: dateUTF8 ( '%d/%m/%Y %H:%M:%S' , $item [ 1 ]);
});
2024-01-04 16:24:00 +01:00
self :: $userStat [ 'floor' ] = helper :: dateUTF8 ( '%d %B %Y %H:%M' , $floorTime );
self :: $userStat [ 'top' ] = helper :: dateUTF8 ( '%d %B %Y %H:%M' , $topTime );
2023-12-09 23:35:21 +01:00
$d = $topTime - $floorTime ;
2024-02-03 09:55:38 +01:00
// Conversion de la différence en jours, heures et minutes
$d_days = floor ( $d / 86400 ); // 1 jour = 86400 secondes (24 heures * 60 minutes * 60 secondes)
$d_hours = floor (( $d % 86400 ) / 3600 );
2023-12-09 23:35:21 +01:00
$d_minutes = floor (( $d % 3600 ) / 60 );
2024-02-03 09:55:38 +01:00
// Affichage du résultat
self :: $userStat [ 'time' ] = $d_days . ' jours, ' . $d_hours . ' heures, ' . $d_minutes . ' minutes ' ;
2023-12-09 17:51:36 +01: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' ]),
2024-02-12 17:21:37 +01:00
'view' => 'userHistory' ,
'vendor' => [
" plotly "
]
2023-10-18 13:41:16 +02:00
]);
}
2023-11-10 17:59:16 +01:00
public function usersHistoryExport ()
2023-11-10 08:59:07 +01:00
{
$courseId = $this -> getUrl ( 2 );
2024-02-12 13:14:02 +01:00
// Accès limité au propriétaire ou éditeurs inscrits ou admin
if (
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2023-12-09 22:45:20 +01:00
self :: $courseUsers = [
2024-01-04 16:24:00 +01:00
0 => [ 'UserId' , 'Prénom' , 'Nom' , 'Page Titre' , 'Consultation Date' , 'Consultation Heure' , 'Progression' ]
2023-12-09 22:45:20 +01:00
];
2023-11-15 18:06:49 +01:00
// Statistiques du contenu sélectionné calcul du nombre de pages
2023-11-10 08:59:07 +01:00
$sumPages = 0 ;
$data = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
// Exclure les barres et les pages masquées
foreach ( $data [ 'page' ] as $pageId => $pageData ) {
if ( $pageData [ 'position' ] > 0 ) {
$sumPages ++ ;
$pages [ $pageId ] = $pageData [ 'title' ];
}
}
2023-11-15 18:06:49 +01:00
// Liste des inscrits dans le contenu sélectionné.
2023-11-10 08:59:07 +01:00
$users = $this -> getData ([ 'enrolment' , $courseId ]);
2024-01-18 22:16:59 +01:00
if ( is_array ( $users )) {
// Tri du tableau par défaut par $userId
ksort ( $users );
2023-11-10 08:59:07 +01:00
2024-01-30 18:57:24 +01:00
// Dossier d'export
if ( is_dir ( self :: FILE_DIR . 'source/' . $courseId ) === false ) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId );
2024-01-18 22:16:59 +01:00
}
2024-01-30 18:57:24 +01:00
if ( is_dir ( self :: FILE_DIR . 'source/' . $courseId . '/export/' ) === false ) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId . '/export/' );
2024-01-18 22:16:59 +01:00
}
2024-01-30 18:57:24 +01:00
$filename = self :: FILE_DIR . 'source/' . $courseId . '/export/' . '/synthèse' . helper :: dateUTF8 ( '%Y%m%d' , time ()) . '.csv' ;
2023-11-10 17:59:16 +01:00
2024-01-18 22:16:59 +01:00
foreach ( $users as $userId => $userValue ) {
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
// Date et heure de la dernière page vue
// Compatibilité anciennes versions
if (
$this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ]) === null
or $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ]) === null
) {
if ( ! empty ( $userValue [ 'history' ])) {
$maxTime = max ( $userValue [ 'history' ]);
$lastPageId = array_search ( $maxTime , $userValue [ 'history' ]);
$this -> setData ([ 'enrolment' , $courseId , $userId , 'lastPageView' , $lastPageId ]);
$this -> setData ([ 'enrolment' , $courseId , $userId , 'datePageView' , $maxTime ]);
}
2023-12-09 22:45:20 +01:00
}
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
// Progression
$viewPages = $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]) !== null ?
count ( array_keys ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]))) :
0 ;
// Construction du tableau
self :: $courseUsers [] = [
$userId ,
$this -> getData ([ 'user' , $userId , 'firstname' ]),
$this -> getData ([ 'user' , $userId , 'lastname' ]),
2024-01-30 18:51:19 +01:00
isset ( $pages [ $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])])
2024-01-30 18:57:24 +01:00
? $pages [ $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])]
: $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ]) . ' (supprimée)' ,
2024-01-18 22:16:59 +01:00
helper :: dateUTF8 ( '%d/%d/%Y' , $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])),
helper :: dateUTF8 ( '%H:%M' , $this -> getData ([ 'enrolment' , $courseId , $userId , 'datePageView' ])),
2024-01-30 18:51:19 +01:00
number_format ( min ( round (( $viewPages * 100 ) / $sumPages , 1 ) / 100 , 1 ), 2 , ',' )
2024-01-18 22:16:59 +01:00
];
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
// Synthèse des historiques
// ------------------------
// Ouverture du fichier en écriture
$file = fopen ( $filename , 'w' );
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
foreach ( self :: $courseUsers as $user ) {
// Décode les entités HTML dans chaque élément du tableau
$decodedUser = array_map ( 'html_entity_decode' , $user );
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
// Écrire la ligne dans le fichier CSV
fputcsv ( $file , $decodedUser , ';' );
}
// Fermeture du fichier
fclose ( $file );
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/users/' . $courseId ,
'notification' => 'Création ' . basename ( $filename ) . ' dans le dossier "Export"' ,
'state' => true ,
]);
2023-11-10 08:59:07 +01:00
2024-01-18 22:16:59 +01:00
}
2023-11-10 08:59:07 +01:00
}
}
2023-11-10 17:59:16 +01:00
public function userHistoryExport ()
{
$courseId = $this -> getUrl ( 2 );
$userId = $this -> getUrl ( 3 );
2024-02-09 15:38:32 +01:00
2024-02-12 13:14:02 +01:00
// Accès limité au propriétaire ou éditeur inscrit ou admin
if (
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2024-02-09 15:38:32 +01:00
// Traitement de l'historique
$h = $this -> getData ([ 'enrolment' , $courseId , $userId , 'history' ]);
// Inversion des clés et des valeurs
$history = array ();
foreach ( $h as $key => $values ) {
foreach ( $values as $value ) {
$history [ $value ] = $key ;
}
}
ksort ( $history );
2023-12-09 17:45:31 +01:00
// Liste des pages contenues dans cet espace et exclure les barres et les pages masquées
2024-02-09 15:38:32 +01:00
$p = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
foreach ( $p [ 'page' ] as $pageId => $pageData ) {
2023-11-10 17:59:16 +01:00
if ( $pageData [ 'position' ] > 0 ) {
$pages [ $pageId ] = [
'title' => $pageData [ 'title' ],
];
}
}
2023-12-09 17:45:31 +01:00
2024-02-09 15:38:32 +01:00
$lastView = 0 ;
2023-12-09 22:45:20 +01:00
2024-02-09 15:38:32 +01:00
foreach ( $history as $time => $pageId ) {
if ( isset ( $pages [ $pageId ][ 'title' ])) {
$lastView = ( $lastView === 0 ) ? $time : $lastView ;
$diff = $time - $lastView ;
2023-12-09 17:45:31 +01:00
self :: $userHistory [] = [
$pageId ,
html_entity_decode ( $pages [ $pageId ][ 'title' ]),
2024-02-09 15:38:32 +01:00
$time ,
( $diff < 1800 ) ? sprintf ( " %d' %d'' " , floor ( $diff / 60 ), $diff % 60 ) : " Non significatif " ,
2023-12-09 17:45:31 +01:00
];
2024-02-09 15:38:32 +01:00
$lastView = $time ;
$floorTime = isset ( $floorTime ) && $floorTime < $time ? $floorTime : $time ;
$topTime = isset ( $topTime ) && $topTime > $time ? $topTime : $time ;
2023-12-09 17:45:31 +01:00
}
}
2023-11-10 17:59:16 +01:00
2024-02-09 15:38:32 +01:00
// Décale les temps de consultation
for ( $i = 0 ; $i < count ( self :: $userHistory ) - 1 ; $i ++ ) {
self :: $userHistory [ $i ][ 3 ] = self :: $userHistory [ $i + 1 ][ 3 ];
}
// Formate le timestamp
array_walk ( self :: $userHistory , function ( & $item ) {
$item [ 2 ] = helper :: dateUTF8 ( '%d/%m/%Y %H:%M:%S' , $item [ 2 ]);
});
// Ajoute les entêtes
self :: $userHistory = array_merge ([ 0 => [ 'PageId' , 'Page Titre' , 'Consultation Date' , 'Temps Consultation' ]], self :: $userHistory );
2024-01-30 18:57:24 +01:00
// Dossier d'export
if ( is_dir ( self :: FILE_DIR . 'source/' . $courseId ) === false ) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId );
2023-12-09 17:45:31 +01:00
}
2024-01-30 18:57:24 +01:00
if ( is_dir ( self :: FILE_DIR . 'source/' . $courseId . '/export/' ) === false ) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId . '/export/' );
2023-12-09 17:45:31 +01:00
}
2024-01-30 18:57:24 +01:00
$filename = self :: FILE_DIR . 'source/' . $courseId . '/export/' . $userId . '.csv' ;
2023-12-09 17:45:31 +01:00
$file = fopen ( $filename , 'w' );
2023-12-09 17:51:36 +01:00
2023-12-09 17:45:31 +01:00
foreach ( self :: $userHistory as $keys => $values ) {
$data = $values ;
2023-11-10 17:59:16 +01:00
// Écrire la ligne dans le fichier CSV
fputcsv ( $file , $data , ';' );
}
// Fermeture du fichier
fclose ( $file );
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/userHistory/' . $courseId . '/' . $userId ,
'notification' => 'Création ' . basename ( $filename ) . ' dans le dossier "Export"' ,
'state' => true ,
]);
}
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 :
2024-01-21 12:02:26 +01:00
if ( $this -> getInput ( 'courseSwapEnrolmentKey' , helper :: FILTER_STRING_SHORT , 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-11-10 17:59:16 +01:00
'redirect' => helper :: baseUrl () . '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 == '' ) {
2023-12-07 10:40:47 +01:00
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Connectez-vous pour accéder à ce espace.' );
2023-10-06 21:24:50 +02:00
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 == '' ) {
2023-12-07 10:40:47 +01:00
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Connectez-vous pour accéder à cet espace.' );
2023-10-06 21:24:50 +02:00
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 ;
2023-11-25 14:36:49 +01:00
case self :: COURSE_ENROLMENT_MANDATORY :
self :: $swapMessage [ 'enrolmentMessage' ] = helper :: translate ( 'Vous ne pouvez pas vous inscrire par vous-même.' );
2023-09-25 21:18:06 +02:00
break ;
2023-09-22 19:33:03 +02:00
}
// Valeurs en sortie
$this -> addOutput ([
2023-12-07 10:40:47 +01:00
'title' => sprintf ( helper :: translate ( 'Accéder à l\'espace %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
2024-01-03 16:40:23 +01:00
/**
* Désinscription d ' un participant
*/
2023-10-19 22:53:00 +02:00
public function unsuscribe ()
{
2023-11-15 18:06:49 +01:00
// Désincription du contenu ouvert ou du contenu sélectionné
2023-10-24 15:13:30 +02:00
$courseId = $this -> getUrl ( 2 ) ? $this -> getUrl ( 2 ) : self :: $siteContent ;
2023-11-15 18:06:49 +01:00
// home n'est pas un contenu 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
}
2024-01-03 16:40:23 +01:00
/**
* Sauvegarde d ' un cours sans option
*/
2024-01-04 16:43:45 +01:00
public function backup ()
2024-01-04 16:24:00 +01:00
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
2024-01-04 16:43:45 +01:00
if (
2024-02-12 13:14:02 +01:00
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
2024-01-04 16:43:45 +01:00
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
} else {
2024-01-03 16:40:23 +01:00
2024-01-04 16:43:45 +01:00
// Participants avec historiques
$enrolment = $this -> getData ([ 'enrolment' , $courseId ]);
// Générer un fichier dans le dossier de l'espace
file_put_contents ( self :: DATA_DIR . $courseId . '/enrolment.json' , json_encode ([ $courseId => $enrolment ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ));
2024-01-04 16:24:00 +01:00
2024-01-04 16:43:45 +01:00
// Idem pour les données du cours
$course = $this -> getData ([ 'course' , $courseId ]);
// Générer un fichier dans le dossier de l'espace
file_put_contents ( self :: DATA_DIR . $courseId . '/course.json' , json_encode ([ $courseId => $course ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ));
2024-01-03 16:40:23 +01:00
2024-01-04 16:43:45 +01:00
// Idem pour la catégorie
$category = $this -> getData ([ 'category' , $this -> getData ([ 'course' , $courseId , 'category' ])]);
// Générer un fichier dans le dossier de l'espace
file_put_contents ( self :: DATA_DIR . $courseId . '/category.json' , json_encode ([ $this -> getData ([ 'course' , $courseId , 'category' ]) => $category ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ));
2024-01-03 16:40:23 +01:00
2024-01-04 16:43:45 +01:00
// Génère une archive ZIP
$this -> makeZip ( self :: TEMP_DIR . $courseId . '-' . date ( 'Y-m-d-H-i-s' , time ()) . '.zip' , self :: DATA_DIR . $courseId );
2024-01-04 16:24:00 +01:00
2024-01-04 16:43:45 +01:00
$success = false ;
$message = helper :: translate ( 'Erreur : sauvegarde non générée !' );
// Transférer dans RFM
if ( file_exists ( self :: TEMP_DIR . $courseId . '-' . date ( 'Y-m-d-H-i-s' , time ()) . '.zip' )) {
2024-01-07 16:11:22 +01:00
if ( ! is_dir ( self :: FILE_DIR . 'source/' . $courseId )) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId );
2024-01-04 16:43:45 +01:00
}
if ( ! is_dir ( self :: FILE_DIR . 'source/' . $courseId . '/backup/' )) {
mkdir ( self :: FILE_DIR . 'source/' . $courseId . '/backup/' );
}
copy ( self :: TEMP_DIR . $courseId . '-' . date ( 'Y-m-d-H-i-s' , time ()) . '.zip' , self :: FILE_DIR . 'source/' . $courseId . '/backup/' . $courseId . '-' . date ( 'Y-m-d-H-i-s' , time ()) . '.zip' );
unlink ( self :: TEMP_DIR . $courseId . '-' . date ( 'Y-m-d-H-i-s' , time ()) . '.zip' );
$success = true ;
$message = helper :: translate ( 'Sauvegarde générée avec succès' );
2024-01-04 16:24:00 +01:00
}
2024-01-04 16:43:45 +01:00
// Valeurs en sortie
$this -> addOutput ([
2024-01-14 19:30:14 +01:00
'redirect' => helper :: baseUrl () . 'course/manage/' . $this -> getUrl ( 2 ),
2024-01-04 16:43:45 +01:00
'state' => $success ,
'notification' => $message ,
]);
2024-01-04 16:24:00 +01:00
}
2024-01-03 16:40:23 +01:00
2024-01-04 16:43:45 +01:00
}
/**
* Sauvegarde d ' un cours sans option
*/
public function restore ()
{
2024-02-12 13:14:02 +01:00
// Espace sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
if (
$this -> permissionControl ( __FUNCTION__ , $courseId ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
2024-01-07 16:11:22 +01:00
// Soumission du formulaire
if (
$this -> isPost ()
) {
2024-01-08 17:24:05 +01:00
// Récupérer le dossier du profil
$userPath = $this -> getData ([ 'profil' , $this -> getuser ( 'group' ), $this -> getuser ( 'profil' ), 'folder' , 'path' ]);
$userPath = $userPath === '' ? self :: $siteContent : $userPath ;
// Fichier avec le bon chemin selon le profil
$zipName = self :: FILE_DIR . 'source/' . $userPath . '/' . $this -> getInput ( 'courseRestoreFile' , null , true );
// Existence de l'archive
2024-01-07 16:11:22 +01:00
if (
2024-01-08 17:24:05 +01:00
$zipName !== '' &&
file_exists ( $zipName )
) {
// Init variables de retour
$success = false ;
$notification = '' ;
// Dossier temporaire
$tempFolder = uniqid ();
// Ouvrir le zip
$zip = new ZipArchive ();
if ( $zip -> open ( $zipName ) === TRUE ) {
mkdir ( self :: TEMP_DIR . $tempFolder , 0755 );
$zip -> extractTo ( self :: TEMP_DIR . $tempFolder );
// Drapeaux de gestion des erreurs
$success = false ;
$notification = '' ;
// Récupérer les données de base à intégrer
$courseData = array ();
if ( file_exists ( self :: TEMP_DIR . $tempFolder . '/course.json' )) {
$courseData = json_decode ( file_get_contents ( self :: TEMP_DIR . $tempFolder . '/course.json' ), true );
// Lire l'id du cours
$courseIds = array_keys ( $courseData );
;
$courseId = $courseIds [ 0 ];
$success = true ;
} else {
// Pas une archive d'espace
$notification = helper :: translate ( 'Archive invalide' );
}
if ( $success && $courseId ) {
// récupérer les inscriptions disponibles
$enrolmentData = array ();
if ( file_exists ( self :: TEMP_DIR . $tempFolder . '/enrolment.json' )) {
$enrolmentData = json_decode ( file_get_contents ( self :: TEMP_DIR . $tempFolder . '/enrolment.json' ), true );
}
// Créer le dossier absent
if ( ! is_dir ( self :: DATA_DIR . $courseId )) {
mkdir ( self :: DATA_DIR . $courseId );
$notification = sprintf ( helper :: translate ( 'Importation terminée : l\'espace %s a été créé' ), $courseId );
} else {
$notification = sprintf ( helper :: translate ( 'Importation terminée : l\'espace %s a été actualisé' ), $courseId );
}
// traiter l'archive
$success = $zip -> extractTo ( self :: DATA_DIR . $courseId );
$zip -> close ();
// Effacer les données de transport
unlink ( self :: DATA_DIR . $courseId . '/course.json' );
unlink ( self :: DATA_DIR . $courseId . '/enrolment.json' );
// Fusionne les deux tableaux
$c = $this -> getData ([ 'course' ]);
$courseData = array_merge ( $c , $courseData );
$e = $this -> getData ([ 'enrolment' ]);
$enrolmentData = array_merge ( $e , $enrolmentData );
// Sauvegarde les bases
$this -> setData ([ 'course' , $courseData ]);
$this -> setData ([ 'enrolment' , $enrolmentData ]);
// traitement d'erreur en cas de problème de désachivage
$notification = $success ? $notification : helper :: translate ( 'Erreur lors de l\'extraction, vérifiez les permissions' );
}
// Supprimer le dossier temporaire même si le thème est invalide
$this -> deleteDir ( self :: TEMP_DIR . $tempFolder );
} else {
// erreur à l'ouverture
$success = false ;
$notification = helper :: translate ( 'Impossible d\'ouvrir l\'archive' );
}
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'state' => $success ,
'notification' => $notification ,
]);
}
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'state' => $success ,
'notification' => $notification ,
]);
2024-01-07 16:11:22 +01:00
}
2024-01-03 16:40:23 +01:00
// Valeurs en sortie
$this -> addOutput ([
2024-01-04 16:43:45 +01:00
'title' => helper :: translate ( 'Restaurer un espace' ),
'view' => 'restore'
2024-01-03 16:40:23 +01:00
]);
}
2023-10-18 13:41:16 +02:00
2024-02-12 13:14:02 +01:00
2023-09-25 21:18:06 +02:00
/**
2024-02-12 13:14:02 +01:00
* Retourne false quand l 'utilisateur ne dispose pas des droits d' accès à la fonction
* Règles d ' accès à un espace :
* Admin : tous les droits
* Editor : Inscrits dans le cours ou propriétaire
2023-09-25 21:18:06 +02:00
*/
2024-02-12 13:14:02 +01:00
public function permissionControl ( $funtion , $courseId )
2023-09-25 21:18:06 +02:00
{
2024-02-12 17:21:37 +01:00
switch ( $this -> getUser ( 'group' )) {
2023-09-25 21:18:06 +02:00
case self :: GROUP_ADMIN :
2024-02-12 13:27:56 +01:00
return true ;
2023-09-25 21:18:06 +02:00
case self :: GROUP_EDITOR :
2024-02-12 13:14:02 +01:00
return (
2024-02-12 13:27:56 +01:00
$this -> getUser ( 'group' ) === self :: $actions [ $funtion ]
2024-02-12 17:21:37 +01:00
&&
( $this -> getData ([ 'enrolment' , $courseId ]) && ( $this -> getUser ( 'id' ) === $this -> getData ([ 'course' , $courseId , 'author' ]))
2024-02-13 10:28:30 +01:00
|| ( // permission de gérer tous les espaces dans lesquels l'éditeur est inscrit.
$this -> getUser ( 'permission' , __CLASS__ , 'index' ) === true &&
array_key_exists ( $this -> getUser ( 'id' ), $this -> getData ([ 'enrolment' , $courseId ]))) )
2024-02-12 13:14:02 +01:00
);
2023-09-25 21:18:06 +02:00
default :
2024-02-12 13:14:02 +01:00
return false ;
2023-09-25 21:18:06 +02:00
}
}
2023-09-22 19:33:03 +02:00
2024-02-12 13:14:02 +01:00
2023-09-25 21:18:06 +02:00
/**
2023-11-15 18:06:49 +01:00
* Autorise l ' accès à un contenu
* @ param @ return bool le user a le droit d ' entrée dans le contenu
* @ param string $courseId identifiant du contenu sollicité
2023-09-25 21:18:06 +02:00
*/
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 ;
}
2024-01-08 17:24:05 +01:00
// Si un utilisateur connecté est admin ou auteur, c'est autorisé
2023-10-02 22:18:13 +02:00
if (
$this -> getUser ( 'password' ) === $this -> getInput ( 'ZWII_USER_PASSWORD' ) &&
2024-01-08 17:24:05 +01:00
( $this -> getUser ( 'group' ) === self :: GROUP_ADMIN ||
$this -> getUser ( 'id' ) === $this -> getData ([ 'course' , $courseId , 'author' ]))
2023-10-02 22:18:13 +02:00
) {
return true ;
}
2023-11-15 18:06:49 +01:00
// Retourne le statut du contenu 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' => [],
]
]);
}
2024-02-12 13:14:02 +01:00
/**
* Autorise l ' accès à un contenu
* @ param @ return bool le user a le droit d ' entrée dans le contenu
* @ param string $userId identifiant de l ' utilisateur
* @ param string $courseId identifiant du contenu sollicité
*/
private function courseIsUserEnroled ( $courseId )
{
$userId = $this -> getUser ( 'id' );
$group = $userId ? $this -> getData ([ 'user' , $userId , 'group' ]) : null ;
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 :
case null :
$r = $this -> getData ([ 'course' , $courseId , 'enrolment' ]) === self :: COURSE_ENROLMENT_GUEST ;
break ;
default :
$r = false ;
}
return $r ;
}
2023-09-08 10:12:23 +02:00
}