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 ,
2024-02-13 12:51:17 +01:00
'index' => self :: GROUP_EDITOR , // Fait
'edit' => self :: GROUP_EDITOR , // Fait
'manage' => self :: GROUP_EDITOR , // Fait
2024-02-13 11:22:49 +01:00
'users' => self :: GROUP_EDITOR , // fait
2024-02-13 14:55:57 +01:00
'usersAdd' => self :: GROUP_EDITOR , //Fait
'usersDelete' => self :: GROUP_EDITOR , //Fait
2024-04-11 07:46:27 +02:00
'usersReportExport' => self :: GROUP_EDITOR , //fait
2024-02-13 12:51:17 +01:00
'userDelete' => self :: GROUP_EDITOR , //Fait
2024-04-11 07:44:43 +02:00
'userReport' => self :: GROUP_EDITOR , //Fait
2024-04-11 07:46:27 +02:00
'userReportExport' => self :: GROUP_EDITOR , //Fait
2024-02-13 12:51:17 +01:00
'backup' => self :: GROUP_EDITOR , // Fait
'restore' => self :: GROUP_EDITOR , //Fait
2024-04-17 10:33:00 +02:00
'reset' => self :: GROUP_EDITOR ,
2024-02-12 13:14:02 +01:00
'clone' => self :: GROUP_ADMIN ,
2024-02-13 14:55:57 +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 ,
2024-09-03 18:54:41 +02:00
'export' => 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
2024-04-11 07:44:43 +02:00
public static $userReport = [];
2023-10-18 13:41:16 +02:00
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-09-03 21:38:12 +02:00
2024-09-03 19:04:37 +02:00
// Pointer RFM sur le dossier de l'espace
self :: $siteContent = 'home' ;
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 ;
2024-04-09 18:32:05 +02:00
$info = sprintf ( ' <a href="%s">%s</a><br />Auteur : %s<br />Id : %s<br />' , $categorieUrl , $this -> getData ([ 'course' , $courseId , 'title' ]), $author , $courseId , );
2024-02-12 13:14:02 +01:00
$enrolment = sprintf (
'Accès : %s<br />Inscription : %s<br />' ,
self :: $courseAccess [ $this -> getData ([ 'course' , $courseId , 'access' ])],
self :: $courseEnrolment [ $this -> getData ([ 'course' , $courseId , 'enrolment' ])]
);
2024-04-23 18:09:28 +02:00
if ( $this -> getUser ( 'permission' , 'course' , 'users' ) === true ) {
$users = template :: button ( 'categoryUser' . $this -> getUrl ( 2 ), [
'href' => helper :: baseUrl () . 'course/users/' . $courseId ,
'value' => template :: ico ( 'users' ),
]);
}
2024-02-12 13:14:02 +01:00
self :: $courses [] = [
$info ,
$this -> getData ([ 'course' , $courseId , 'description' ]),
$enrolment ,
2024-04-23 18:09:28 +02:00
$users ,
2024-02-12 13:14:02 +01:00
template :: button ( 'categoryUser' . $courseId , [
'href' => helper :: baseUrl () . 'course/manage/' . $courseId ,
2024-04-23 18:09:28 +02:00
'value' => template :: ico ( 'sliders' ),
2024-02-12 13:14:02 +01:00
'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 );
2024-09-03 19:04:37 +02:00
// Pointer RFM sur le dossier de l'espace
2024-09-03 19:02:02 +02:00
self :: $siteContent = $courseId ;
2024-09-03 21:38:12 +02:00
// Ordonne les pages par position
$this -> buildHierarchy ();
2024-09-03 19:02:02 +02:00
2023-10-04 17:57:07 +02:00
// 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
2024-09-03 18:54:41 +02:00
$this -> initDB ( 'page' , $courseId );
2024-09-04 08:25:10 +02:00
2024-09-03 19:04:37 +02:00
// Pointer RFM sur le dossier de l'espace
2024-09-03 19:02:02 +02:00
self :: $siteContent = $courseId ;
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Ordonne les pages par position
$this -> buildHierarchy ();
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Données pour le formulaire
2023-09-30 13:35:20 +02:00
self :: $pagesList = $this -> getData ([ 'page' ]);
2024-09-04 08:25:10 +02:00
// Exclure les barres et les pages désactivées
foreach ( self :: $pagesList as $pageId => $page ) {
if (
$page [ 'block' ] === 'bar' ||
$page [ 'disable' ] === true
) {
unset ( self :: $pagesList [ $pageId ]);
}
}
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
2024-09-03 18:54:41 +02:00
$this -> initDB ( 'page' , $courseId );
2024-09-04 08:25:10 +02:00
2024-09-03 19:04:37 +02:00
// Pointer RFM sur le dossier de l'espace
2024-09-03 19:02:02 +02:00
self :: $siteContent = $courseId ;
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Ordonne les pages par position
$this -> buildHierarchy ();
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Données pour le formulaire
2024-01-14 20:56:23 +01:00
self :: $pagesList = $this -> getData ([ 'page' ]);
2024-09-04 08:30:38 +02:00
2024-09-04 08:25:10 +02:00
// Exclure les barres et les pages désactivées
foreach ( self :: $pagesList as $pageId => $page ) {
if (
$page [ 'block' ] === 'bar' ||
$page [ 'disable' ] === true
) {
unset ( self :: $pagesList [ $pageId ]);
}
}
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-03-18 18:14:27 +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-10-20 16:07:58 +02:00
$sumPages = $this -> countPages ( $pages [ 'page' ]);
2024-04-12 22:04:24 +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-10-20 16:07:58 +02:00
// Obtient les statistiques de l'ensemble de la cohorte
2024-04-12 22:04:24 +02:00
$reports = $this -> getReport ( $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-10-17 19:17:04 +02:00
2024-01-18 22:16:59 +01:00
// Compte les rôles valides
2024-04-12 22:04:24 +02:00
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
2024-01-18 22:16:59 +01:00
$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
2024-04-12 22:04:24 +02:00
$viewPages = array_key_exists ( $userId , $reports ) ?
count ( $reports [ $userId ]) :
2024-01-18 22:16:59 +01:00
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' ]),
2024-04-17 10:33:00 +02:00
array_key_exists ( 'lastPageView' , $userValue ) && isset ( $pages [ $userValue [ 'lastPageView' ]][ 'title' ])
2024-04-12 22:04:24 +02:00
? $pages [ $userValue [ 'lastPageView' ]][ 'title' ]
2024-01-18 22:16:59 +01:00
: '' ,
2024-04-17 10:33:00 +02:00
array_key_exists ( 'lastPageView' , $userValue )
2024-04-12 22:04:24 +02:00
? helper :: dateUTF8 ( '%d/%m/%Y' , $userValue [ 'datePageView' ])
2024-02-08 19:39:51 +01:00
: '' ,
2024-04-17 10:33:00 +02:00
array_key_exists ( 'datePageView' , $userValue )
2024-04-12 22:04:24 +02:00
? helper :: dateUTF8 ( '%H:%M' , $userValue [ 'datePageView' ])
2024-01-18 22:16:59 +01:00
: '' ,
$this -> getData ([ 'user' , $userId , 'tags' ]),
2024-04-11 07:44:43 +02:00
template :: button ( 'userReport' . $userId , [
'href' => helper :: baseUrl () . 'course/userReport/' . $courseId . '/' . $userId ,
2024-10-25 09:25:16 +02:00
/** La lecture de la progression s ' effectue selon la nouvelle méthode ( progression dans la base des enrolements )
* Soit avec l ' ancienne méthode qui consiste à recalculer la progression .
* TRANSITOIRE A SUPPRIMER EN FIN D ' ANNEE
**/
2024-12-05 17:55:27 +01:00
/*
2024-10-25 09:25:16 +02:00
'value' => array_key_exists ( 'progress' , $userValue )
? $userValue [ 'progress' ]
: ( $viewPages ? min ( round (( $viewPages * 100 ) / $sumPages , 1 ), 100 ) . ' %' : '0%' ),
'disable' => empty ( $userValue [ 'datePageView' ]),
2024-12-05 17:55:27 +01:00
*/
'value' => $viewPages ? min ( round (( $viewPages * 100 ) / $sumPages , 1 ), 100 ) . ' %' : '0%' ,
2024-10-25 09:25:16 +02:00
//'disable' => empty($viewPages)
2024-01-18 22:16:59 +01:00
]),
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 (
2024-04-12 22:04:24 +02:00
isset ( $_POST [ 'courseUsersAddSubmit' ])
2023-11-23 11:25:42 +01:00
) {
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
) {
2024-09-28 13:24:55 +02:00
$this -> setData ([ 'enrolment' , $courseId , $keyPost , 'history' , array ()], false );
2023-11-23 08:47:00 +01:00
}
}
2024-09-28 13:24:55 +02:00
// Sauvegarde la base manuellement
2024-10-20 16:07:58 +02:00
$this -> saveDB ( 'enrolment' );
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
2024-04-12 22:04:24 +02:00
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
2023-11-30 14:26:11 +01:00
$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 (
2024-04-12 22:04:24 +02:00
isset ( $_POST [ 'courseFilterGroup' ])
|| isset ( $_POST [ 'courseFilterFirstName' ])
|| isset ( $_POST [ 'courseFilterLastName' ])
2023-11-23 11:25:42 +01:00
) {
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
2024-04-17 10:33:00 +02:00
* Les désinscriptions ne suppriment pas les historiques
2023-10-08 14:46:44 +02:00
*/
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 (
2024-04-12 22:04:24 +02: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
2024-04-12 22:04:24 +02:00
if ( isset ( $profils [ $this -> getData ([ 'user' , $userId , 'group' ]) . $this -> getData ([ 'user' , $userId , 'profil' ])])) {
2024-01-18 22:16:59 +01:00
$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-04-12 22:04:24 +02:00
isset ( $_POST [ 'courseFilterGroup' ])
|| isset ( $_POST [ 'courseFilterFirstName' ])
|| isset ( $_POST [ 'courseFilterLastName' ])
2024-01-18 22:16:59 +01:00
) {
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
}
2024-04-17 10:33:00 +02:00
/**
* Désincription de tous les utilisateurs hors les éditeurs
* Effacement des historiques
*/
public function reset ()
{
// Contenu 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
]);
}
// Active l'accueil
$_SESSION [ 'ZWII_SITE_CONTENT' ] = 'home' ;
// Efface les inscriptions
$success = $this -> setData ([ 'enrolment' , $courseId , []]);
// Efface les rapports
if ( file_exists ( self :: DATA_DIR . $courseId . '/report.csv' )) {
unlink ( self :: DATA_DIR . $courseId . '/report.csv' );
}
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course' ,
'notification' => helper :: translate ( 'Espace 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-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
2024-02-14 11:38:29 +01:00
// Récupérer les pages pour contrôler la dernière page vue
2024-02-13 11:33:03 +01:00
$p = json_decode ( file_get_contents ( self :: DATA_DIR . $courseId . '/page.json' ), true );
$pages = $p [ 'page' ];
// Routage
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 )
2024-03-18 18:14:27 +01:00
) {
2023-10-01 20:59:48 +02:00
// Récupérer la dernière page visitée par cet utilisateur si elle existe
2024-03-18 18:14:27 +01:00
$redirect = ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ]) !== null
&& array_key_exists ( $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ]), $pages )
)
2023-12-09 13:25:18 +01:00
? helper :: baseUrl () . $this -> getData ([ 'enrolment' , $courseId , $userId , 'lastPageView' ])
2024-02-14 11:38:29 +01:00
: helper :: baseUrl ();
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
*/
2024-04-11 07:44:43 +02:00
public function userReport ()
2023-10-18 13:41:16 +02:00
{
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-04-13 10:05:32 +02:00
$h = $this -> getReport ( $courseId , $userId );
$h = $h [ $userId ];
2024-02-09 15:38:32 +01:00
// Inversion des clés et des valeurs
2024-04-13 10:05:32 +02:00
$report = array ();
2024-02-09 15:38:32 +01:00
foreach ( $h as $key => $values ) {
foreach ( $values as $value ) {
2024-04-13 10:05:32 +02:00
$report [ $value ] = $key ;
2024-02-09 15:38:32 +01:00
}
}
2024-04-13 10:05:32 +02:00
ksort ( $report );
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-04-13 10:05:32 +02:00
foreach ( $report as $time => $pageId ) {
2024-04-12 22:04:24 +02:00
if ( isset ( $pages [ $pageId ][ 'title' ])) {
2024-02-09 15:38:32 +01:00
$lastView = ( $lastView === 0 ) ? $time : $lastView ;
$diff = $time - $lastView ;
2024-04-11 07:44:43 +02:00
self :: $userReport [] = [
2024-02-09 15:38:32 +01:00
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 14:55:57 +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 ;
2024-04-12 22:04:24 +02:00
$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
2024-04-11 07:44:43 +02:00
for ( $i = 0 ; $i < count ( self :: $userReport ) - 1 ; $i ++ ) {
self :: $userReport [ $i ][ 2 ] = self :: $userReport [ $i + 1 ][ 2 ];
2024-02-09 15:38:32 +01:00
}
2024-02-13 08:43:09 +01:00
// Décale les temps de consultation
for ( $i = 0 ; $i < count ( self :: $userGraph ) - 1 ; $i ++ ) {
2024-04-11 07:44:43 +02:00
self :: $userReport [ $i ][ 1 ] = self :: $userReport [ $i + 1 ][ 1 ];
2024-02-13 08:43:09 +01:00
}
2024-02-09 15:38:32 +01:00
// Formate le timestamp
2024-04-11 07:44:43 +02:00
array_walk ( self :: $userReport , function ( & $item ) {
2024-02-09 15:38:32 +01:00
$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-04-11 07:44:43 +02:00
'view' => 'userReport' ,
2024-02-12 17:21:37 +01:00
'vendor' => [
" plotly "
]
2023-10-18 13:41:16 +02:00
]);
}
2024-04-11 07:46:27 +02:00
public function usersReportExport ()
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-10-25 10:20:31 +02:00
0 => [ 'UserId' , 'Prénom' , 'Nom' , 'Mail' , '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-10-20 17:59:08 +02:00
// Obtient les statistiques de l'ensemble de la cohorte
$reports = $this -> getReport ( $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
) {
2024-04-12 22:04:24 +02:00
if ( ! empty ( $userValue [ 'history' ])) {
2024-01-18 22:16:59 +01:00
$maxTime = max ( $userValue [ 'history' ]);
$lastPageId = array_search ( $maxTime , $userValue [ 'history' ]);
2024-09-28 13:24:55 +02:00
$this -> setData ([ 'enrolment' , $courseId , $userId , 'lastPageView' , $lastPageId ], false );
2024-01-18 22:16:59 +01:00
$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
2024-10-20 17:59:08 +02:00
$viewPages = array_key_exists ( $userId , $reports ) ?
count ( $reports [ $userId ]) :
2024-01-18 22:16:59 +01:00
0 ;
// Construction du tableau
self :: $courseUsers [] = [
$userId ,
$this -> getData ([ 'user' , $userId , 'firstname' ]),
$this -> getData ([ 'user' , $userId , 'lastname' ]),
2024-10-25 10:04:01 +02:00
$this -> getData ([ 'user' , $userId , 'mail' ]),
2024-04-12 22:04:24 +02: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-10-25 09:25:16 +02:00
/** La lecture de la progression s ' effectue selon la nouvelle méthode ( progression dans la base des enrolements )
* Soit avec l ' ancienne méthode qui consiste à recalculer la progression .
* TRANSITOIRE A SUPPRIMER EN FIN D ' ANNEE
**/
array_key_exists ( 'progress' , $userValue )
? $userValue [ 'progress' ]
: ( $viewPages ? min ( round (( $viewPages * 100 ) / $sumPages , 1 ), 100 ) . ' %' : '0%' ),
//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
}
}
2024-04-11 07:46:27 +02:00
public function userReportExport ()
2023-11-10 17:59:16 +01:00
{
$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
2024-04-17 10:33:00 +02:00
$h = $this -> getReport ( $courseId );
2024-04-13 10:05:32 +02:00
$h = $h [ $userId ];
2024-02-09 15:38:32 +01:00
// Inversion des clés et des valeurs
2024-04-13 10:05:32 +02:00
$report = array ();
2024-02-09 15:38:32 +01:00
foreach ( $h as $key => $values ) {
foreach ( $values as $value ) {
2024-04-13 10:05:32 +02:00
$report [ $value ] = $key ;
2024-02-09 15:38:32 +01:00
}
}
2024-04-13 10:05:32 +02:00
ksort ( $report );
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-04-13 10:05:32 +02:00
foreach ( $report as $time => $pageId ) {
2024-04-12 22:04:24 +02:00
if ( isset ( $pages [ $pageId ][ 'title' ])) {
2024-02-09 15:38:32 +01:00
$lastView = ( $lastView === 0 ) ? $time : $lastView ;
$diff = $time - $lastView ;
2024-04-11 07:44:43 +02:00
self :: $userReport [] = [
2023-12-09 17:45:31 +01:00
$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 ;
2024-04-12 22:04:24 +02:00
$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
2024-04-11 07:44:43 +02:00
for ( $i = 0 ; $i < count ( self :: $userReport ) - 1 ; $i ++ ) {
self :: $userReport [ $i ][ 3 ] = self :: $userReport [ $i + 1 ][ 3 ];
2024-02-09 15:38:32 +01:00
}
// Formate le timestamp
2024-04-11 07:44:43 +02:00
array_walk ( self :: $userReport , function ( & $item ) {
2024-02-09 15:38:32 +01:00
$item [ 2 ] = helper :: dateUTF8 ( '%d/%m/%Y %H:%M:%S' , $item [ 2 ]);
});
// Ajoute les entêtes
2024-04-11 07:44:43 +02:00
self :: $userReport = array_merge ([ 0 => [ 'PageId' , 'Page Titre' , 'Consultation Date' , 'Temps Consultation' ]], self :: $userReport );
2024-02-09 15:38:32 +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 );
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
2024-04-11 07:44:43 +02:00
foreach ( self :: $userReport as $keys => $values ) {
2023-12-09 17:45:31 +01:00
$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 ([
2024-04-11 07:44:43 +02:00
'redirect' => helper :: baseUrl () . 'course/userReport/' . $courseId . '/' . $userId ,
2023-11-10 17:59:16 +01:00
'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
2024-04-17 10:33:00 +02:00
* La désinscription ne supprime pas les historiques ,
2024-01-03 16:40:23 +01:00
*/
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' );
2024-04-02 18:12:24 +02:00
$this -> deleteData ([ 'enrolment' , $courseId , $userId ]);
2023-10-24 15:13:30 +02:00
$_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
2024-04-09 14:33:01 +02:00
$this -> secure_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
2024-04-09 14:33:01 +02:00
$this -> secure_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
2024-04-09 14:33:01 +02:00
$this -> secure_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
}
2024-09-03 18:54:41 +02:00
// Générer un fichier externe contenant le contenu des pages
public function export ()
{
// Espace sélectionné
$courseId = $this -> getUrl ( 2 );
// Accès limité aux admins, à l'auteur ou éditeurs inscrits
if (
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === false
) {
// Valeurs en sortie
$this -> addOutput ([
'access' => false
]);
}
// Liste des pages disponibles
$this -> initDB ( 'page' , $courseId );
2024-09-04 08:25:10 +02:00
2024-09-03 19:04:37 +02:00
// Pointer RFM sur le dossier de l'espace
2024-09-03 19:02:02 +02:00
self :: $siteContent = $courseId ;
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Ordonne les pages par position
$this -> buildHierarchy ();
2024-09-04 08:25:10 +02:00
2024-09-03 21:38:12 +02:00
// Tableau de retour
2024-09-03 18:54:41 +02:00
self :: $pagesList = [];
2024-09-03 21:38:12 +02:00
2024-09-04 08:25:10 +02:00
// Exclure les barres et les pages désactivées
2024-09-03 18:54:41 +02:00
foreach ( $this -> getData ([ 'page' ]) as $pageId => $page ) {
2024-09-04 08:25:10 +02:00
if (
$this -> getData ([ 'page' , $pageId , 'block' ]) !== 'bar' &&
$this -> getData ([ 'page' , $pageId , 'disable' ]) !== true
) {
self :: $pagesList [] = template :: checkbox ( 'courseManageExport' . $pageId , true , $page [ 'title' ], [
'class' => 'courseManageCheckbox'
]);
}
2024-09-03 18:54:41 +02:00
}
2024-09-04 08:48:10 +02:00
2024-09-03 18:54:41 +02:00
// Soumission du formulaire
if ( $this -> isPost ()) {
2024-09-04 09:34:10 +02:00
$datas = '<h1>' . $this -> getData ([ 'course' , $courseId , 'title' ]) . '</h1>' ;
2024-09-03 18:54:41 +02:00
$resources = [];
2024-09-04 08:30:38 +02:00
foreach ( $this -> getData ([ 'page' ]) as $pageId => $page ) {
2024-09-03 18:54:41 +02:00
if ( $this -> getInput ( 'courseManageExport' . $pageId , helper :: FILTER_BOOLEAN ) === true ) {
$pageContent = $this -> getPage ( $pageId , $courseId );
2024-09-04 08:48:10 +02:00
// Extraction des URLs des ressources (images, vidéos, fichiers, etc.)
preg_match_all ( '/<img[^>]+src=["\'](.*?)["\']/i' , $pageContent , $imgMatches ); // Images
preg_match_all ( '/<a[^>]+href=["\'](.*?)["\']/i' , $pageContent , $linkMatches ); // Liens
preg_match_all ( '/<video[^>]+src=["\'](.*?)["\']/i' , $pageContent , $videoMatches ); // Vidéos directes
preg_match_all ( '/<source[^>]+src=["\'](.*?)["\']/i' , $pageContent , $sourceMatches ); // Vidéos dans balises <source>
2024-09-03 18:54:41 +02:00
2024-09-04 08:48:36 +02:00
// Traitement des images
$this -> processResources ( $pageContent , '/<img[^>]+src=["\'](.*?)["\']/i' , $resources );
2024-09-03 18:54:41 +02:00
2024-09-04 08:48:36 +02:00
// Traitement des vidéos directes via <video>
$this -> processResources ( $pageContent , '/<video[^>]+src=["\'](.*?)["\']/i' , $resources );
2024-09-03 18:54:41 +02:00
2024-09-04 08:48:36 +02:00
// Traitement des sources dans les balises <source> (utilisées dans <video> ou <audio>)
$this -> processResources ( $pageContent , '/<source[^>]+src=["\'](.*?)["\']/i' , $resources );
2024-09-04 08:48:10 +02:00
2024-09-04 08:48:36 +02:00
// Traitement des liens <a>
$this -> processResources ( $pageContent , '/<a[^>]+href=["\'](.*?)["\']/i' , $resources );
2024-09-04 08:48:10 +02:00
// Traitement des liens
2024-09-03 18:54:41 +02:00
if ( ! empty ( $linkMatches [ 1 ])) {
$resources = array_merge ( $resources , $linkMatches [ 1 ]);
// Remplacement des chemins pour les liens dans $pageContent
foreach ( $linkMatches [ 1 ] as $resourceUrl ) {
$resourcePath = parse_url ( $resourceUrl , PHP_URL_PATH );
$resourceFile = basename ( $resourcePath );
$pageContent = str_replace ( $resourceUrl , $resourceFile , $pageContent );
}
}
$datas .= $pageContent ;
}
}
// Créer le dossier d'export
$path = self :: FILE_DIR . 'source/' . $courseId . '/' ;
if ( is_dir ( $path . 'export' ) === false ) {
mkdir ( $path . 'export' );
}
// Copier les ressources dans le dossier d'export
foreach ( $resources as $resourceUrl ) {
$resourcePath = parse_url ( $resourceUrl , PHP_URL_PATH );
$resourceFile = basename ( $resourcePath );
if ( file_exists ( $resourcePath )) { // Utilisation du chemin correct
copy ( $resourcePath , $path . 'export/' . $resourceFile );
}
}
// Ajouter les balises HTML manquantes
$datas = ' <! DOCTYPE html >
2024-09-04 08:48:10 +02:00
< html lang = " fr " >
< head >
< meta charset = " UTF-8 " >
< meta name = " viewport " content = " width=device-width, initial-scale=1.0 " >
< title > ' . $this->getData([' course ', $courseId, ' title ']) . ' </ title >
< link rel = " stylesheet " href = " style.css " >
</ head >
< body > ' . $datas . ' </ body ></ html > ' ;
2024-09-03 18:54:41 +02:00
// Sauvegarder le fichier HTML
2024-09-04 09:34:10 +02:00
file_put_contents ( $path . '/export/export_' . $this -> getData ([ 'course' , $courseId , 'title' ]) . '.html' , $datas , LOCK_EX );
2024-09-03 19:02:02 +02:00
2024-09-03 18:54:41 +02:00
// Copie une feuille de style
2024-09-04 09:27:27 +02:00
copy ( 'core/module/course/resource/style.css' , $path . 'export/style.css' );
2024-09-03 18:54:41 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'course/manage/' . $courseId ,
'notification' => helper :: translate ( 'Pages exportées dans le dossier de cet espace' ),
'state' => true ,
]);
}
// Valeurs en sortie
$this -> addOutput ([
2024-09-04 20:21:42 +02:00
'title' => sprintf ( '%s id : %s' , helper :: translate ( 'Export des pages de l\'espace' ), $this -> getUrl ( 2 )),
2024-09-03 18:54:41 +02:00
'view' => 'export'
]);
}
2024-09-04 09:27:27 +02:00
// Fonction utilisé par l'export en html pour corriger les URL des ressources
2024-09-04 08:48:10 +02:00
private function processResources ( & $pageContent , $regex , & $resources )
{
preg_match_all ( $regex , $pageContent , $matches );
if ( ! empty ( $matches [ 1 ])) {
$resources = array_merge ( $resources , $matches [ 1 ]);
// Remplacement des chemins dans $pageContent
foreach ( $matches [ 1 ] as $resourceUrl ) {
$resourcePath = parse_url ( $resourceUrl , PHP_URL_PATH );
$resourceFile = basename ( $resourcePath );
$pageContent = str_replace ( $resourceUrl , $resourceFile , $pageContent );
}
}
}
2024-01-04 16:43:45 +01:00
/**
2024-09-04 09:27:27 +02:00
* Récupération d ' un espace sans option
2024-01-04 16:43:45 +01:00
*/
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 (
2024-02-16 11:06:54 +01:00
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === false
2024-02-12 13:14:02 +01:00
) {
// 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-13 14:55:57 +01:00
public function permissionControl ( $function , $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-13 14:55:57 +01:00
$this -> getUser ( 'permission' , __CLASS__ , $function )
2024-02-16 11:06:54 +01:00
&& $this -> getUser ( 'group' ) === self :: $actions [ $function ]
2024-02-12 17:21:37 +01:00
&&
2024-02-16 11:06:54 +01:00
// Permission d'accéder aux espaces dans lesquels le membre auteur
2024-02-13 14:55:57 +01:00
(
$this -> getData ([ 'enrolment' , $courseId ]) && ( $this -> getUser ( 'id' ) === $this -> getData ([ 'course' , $courseId , 'author' ]))
)
2024-03-18 18:14:27 +01:00
||
2024-02-16 11:06:54 +01:00
( // Permission d'accéder aux espaces dans lesquels le membre est inscrits
2024-02-13 14:55:57 +01:00
$this -> getData ([ 'enrolment' , $courseId ])
2024-02-14 08:12:33 +01:00
&& $this -> getUser ( 'permission' , __CLASS__ , 'tutor' ) === true
2024-02-13 14:55:57 +01:00
&& 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
2024-10-20 16:07:58 +02:00
* @ return bool le user a le droit d ' entrée dans le contenu
2023-11-15 18:06:49 +01:00
* @ 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 (
2024-09-06 17:16:04 +02:00
$this -> isConnected () === true &&
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 (
2024-12-05 17:55:27 +01:00
time () >= $this -> getData ([ 'course' , $courseId , 'openingDate' ]) &&
2023-09-25 21:18:06 +02:00
time () <= $this -> getData ([ 'course' , $courseId , 'closingDate' ])
);
case self :: COURSE_ACCESS_CLOSE :
2024-10-20 16:07:58 +02:00
default :
2023-09-25 21:18:06 +02:00
return false ;
}
}
2023-09-21 15:34:03 +02:00
2024-10-20 17:59:08 +02:00
/**
2024-12-05 17:55:27 +01:00
* Méthode externe pour calculer la progression dans les espaces et la stocker dans enrolment
2024-10-20 17:59:08 +02:00
*
* @ param mixed $courseId
* @ param mixed $userId
* @ return string Ratio de pages vues
*/
public function userProgress ( $courseId , $userId ) : string
{
// Obtient les statistiques de l'ensemble de la cohorte
$reports = $this -> getReport ( $courseId , $userId );
// Nombre de pages dans l'espace
$viewPages = array_key_exists ( $userId , $reports ) ?
count ( $reports [ $userId ]) :
0 ;
// Nombre de pages vues
$sumPages = $this -> countPages ( $this -> getData ([ 'page' ]));
2024-12-05 17:55:27 +01:00
2024-10-20 17:59:08 +02:00
// Calcule le ratio
2024-12-05 17:55:27 +01:00
$ratio = ( $viewPages * 100 ) / $sumPages ;
// Arrondi le ratio à deux décimales
$ratio = round ( $ratio , 2 );
// Transforme le ratio en pourcentage
$ratio = number_format ( $ratio ) . ' %' ;
2024-10-20 17:59:08 +02:00
return $ratio ;
}
2024-10-20 16:07:58 +02:00
/**
*
* Compte les pages d ' un espace
* @ param mixed $array Tableau des pages de l ' espace
* @ return int Nombre de pages
*/
2023-10-17 11:21:35 +02:00
private function countPages ( $array )
{
2023-10-15 22:34:56 +02:00
$count = 0 ;
2024-10-20 16:07:58 +02:00
foreach ( $array as $pageId => $pageData ) {
if ( $pageData [ 'position' ] > 0 ) {
$count ++ ;
2023-10-15 22:34:56 +02:00
}
}
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 ,
[
2024-10-25 09:25:16 +02:00
'lastPageView' => '' ,
'datePageView' => '' ,
'progress' => '' ,
2023-10-18 13:41:16 +02:00
]
]);
}
2024-02-12 13:14:02 +01:00
/**
* Autorise l ' accès à un contenu
2024-10-20 16:07:58 +02:00
* @ return bool le user a le droit d ' entrée dans le contenu
2024-02-12 13:14:02 +01:00
* @ 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 :
case self :: GROUP_MEMBER :
2024-03-18 18:14:27 +01:00
$r = false ;
if ( ! is_null ( $this -> getData ([ 'enrolment' , $courseId ]))) {
$r = in_array ( $userId , array_keys ( $this -> getData ([ 'enrolment' , $courseId ])));
}
2024-02-12 13:14:02 +01:00
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 ;
}
2024-04-11 07:44:43 +02:00
/**
* Lit le contenu des fichiers de traces au format CS et renvoie un tableau associatif
*/
2024-10-20 17:59:08 +02:00
private function getReport ( $courseId , $userId = null )
2024-04-12 22:04:24 +02:00
{
2024-04-17 10:33:00 +02:00
$data = [];
if ( file_exists ( self :: DATA_DIR . $courseId . '/report.csv' )) {
// Remplacez 'chemin/vers/votre/fichier.csv' par le chemin réel de votre fichier CSV
$file = fopen ( self :: DATA_DIR . $courseId . '/report.csv' , " r " );
$data = array ();
// Lire ligne par ligne
while (( $line = fgetcsv ( $file , 1000 , " ; " )) !== false ) {
$name = $line [ 0 ];
$pageId = $line [ 1 ];
$timestamp = $line [ 2 ];
// Filtre userId
2024-10-20 16:07:58 +02:00
if (
is_null ( $userId ) === false
&& $name !== $userId
) {
continue ;
}
2024-04-12 22:04:24 +02:00
// Initialiser le tableau si nécessaire
if ( ! isset ( $data [ $name ][ $pageId ])) {
$data [ $name ][ $pageId ] = array ();
}
// Ajouter le timestamp
$data [ $name ][ $pageId ][] = $timestamp ;
2024-04-17 10:33:00 +02:00
}
2024-04-12 22:04:24 +02:00
2024-04-17 10:33:00 +02:00
// Fermer le fichier
fclose ( $file );
2024-04-12 22:04:24 +02:00
2024-04-17 10:33:00 +02:00
// Trier les timestamps
foreach ( $data as & $userData ) {
foreach ( $userData as & $pageData ) {
sort ( $pageData );
}
2024-04-11 07:44:43 +02:00
}
}
2024-04-12 22:04:24 +02:00
2024-04-11 07:44:43 +02:00
// Afficher le JSON;
2024-04-12 22:04:24 +02:00
return $data ;
2024-04-11 07:44:43 +02:00
}
2023-09-08 10:12:23 +02:00
}