Commit 0d1bfe99 authored by Thomas Fradet's avatar Thomas Fradet
Browse files

first push

parents
# Competency
This Moodle plugin define the competency management block.
*Authors :*
- Vrignaud Camille *(cvrignaud@softia.fr)*
- Lebeau Michaël *(mlebeau@softia.fr)*
*To install it:*
- Trough the Moodle Administration section "Plugin" -> Add plugin
- Add block in edit mode
## Functionalities :
- My Competencies
- Table of students that have, or not, completed a competency/evaluation/activity
- Manage competencies
- A js table of competencies which you can explore, edit the actions of completion, and add a competency from your referencials. If you don't have access to referencial, you could ask access with a button on the modal.
> \*\*Additional informations:\*\* The plugin was tested in Moodle 3.3 and 3.4
> For more information contact : support_git@softia.fr
## MAJ
### Fait
[x] Affichage du nom du cours et du nom de l'évaluateur en début du texte joint à une évaluation d'une compétence. Ceci permet de se souvenir du contexte de l'évaluation, même si le cours a été supprimé.
[x] Dans la description d'une compétence sur la page qui montre la compétence d'un utilisateur dans le cours, la description est tronquée si elle fait plus de 300 caractères et un lien permet de la déplier / replier. Il y a un ascenseur dans les deux cas.
[x] Ajout de cadres autours des zones de la page pour plus de clareté.
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, remplacement de la description de la compétence par une boîte à onglet avec dans le premier onglet le titre et la description de la compétence (toujours replable et sinon scrollable), et dans le second onglet, un accordéon dont le premier item est déplié avec pour chaque item le nom et la description : du référentiel, puis de chaque parent de la compétence dans le référentiel, avec un item par parent, dans l'ordre de haut en bas (réf, parent niv 1, parent niv 2, etc. ).
[x] Restriction de la hauteur de l'historique à environ deux éléments avec un scroll pour le reste. Suppression du bouton pour tout déplier car il était peu visible.
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, ajout d'un bouton pour passer directement à l'utilisateur précédent / suivant et à la compétence précédente, suivante, sans passer par la liste qui est longue pour les users (surtout pour les users).
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, correction d'un bug qui empêchait le changement d'étudiant en cas d'homonymie.
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, la section qui montre l'historique ne s'affiche plus s'il n'y en a pas.
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, la section qui montre les modules de cours liés ne s'affiche plus s'il n'y en a pas.
[x] Sur la page qui montre la compétence d'un utilisateur dans le cours, ajout d'un lien au début de l'historique qui permet d'aller à la page qui montre la compétence pour un utilisateur en dehors du contexte du cours : http://localhost:8888/moodle35/admin/tool/lp/user_competency.php?id=[[competency_usercomp->id]] ; si cette donnée existe. La donnée existe s'il y a déjà eu une action sur la compétence dans un cours avec l'option de remontée dans les plans de formation activée.
[x] La liste des commentaires est pliée par défaut pour augmenter la lisibilité de la page. Attention, les nouveaux commentaires seront très difficiles à voir, il faudra prévoir une notification.
### En cours
[ ] Sur la page qui montre la compétence d'un utilisateur dans le cours, ajout d'un historique de la compétence comprenant les données du plan de formation (donc celles placées dans le PF, mais aussi celles issues de tous les cours dont les données remontent dans le PF).
( ) Aggréger l'historique de toutes les compétences dans l'historique du cours avec un switch entre les deux ou une autre solution pour voir les autres infos. Peut-être que ce n'est pas l'endroit.
### A faire un jour
[ ] Nettoyer les méthodes persos inutiles dans la page view_competency_iena et passer par l'api.
[ ] Rendre la page qui montre la compétence d'un utilisateur dans le cours jolie et plus facile à lire.
[ ] Modifier l'apparence ou le fonctionnement de la matrice d'ajout et de liaison des compétences aux activités pour qu'elle soit plus pratique à utiliser et plus lisible, surtout pour lier des cpt aux activités.
[ ] Notifier les utilisateurs (lesquels) lors de l'ajout d'un commentaire sur une compétence dans la page qui montre la compétence d'un utilisateur dans le cours.
<?php
require_once('entity/block_competency_iena_competency.php');
class block_competency_iena extends block_base
{
public function init()
{
$this->title = get_string('title_plugin', 'block_competency_iena');
}
function instance_allow_multiple()
{
return false;
}
/**
* Set the applicable formats for this block to all
* @return array
*/
function applicable_formats()
{
return array('course' => true);
}
/**
* Allow the user to configure a block instance
* @return bool Returns true
*/
function instance_allow_config()
{
return true;
}
function has_config()
{
return true;
}
public function get_content()
{
global $CFG;
global $COURSE;
global $USER;
if ($this->content !== null) {
return $this->content;
}
if (empty($this->config)) {
$this->config = new stdClass();
}
$this->content = new stdClass;
if (has_capability('moodle/course:update', $context = context_course::instance($COURSE->id), $USER->id)) {
$this->content->text .= '<a href="' . $CFG->wwwroot . '/blocks/competency_iena/competency_iena_competencies.php?courseid=' . $COURSE->id . '" class="btn btn-primary w-100 mb-3" style="white-space: normal;">Acquisition des compétences</a>';
$this->content->text .= '<a href="' . $CFG->wwwroot . '/blocks/competency_iena/competency_iena_competencies_mgmt.php?courseid=' . $COURSE->id . '" type="button " class="btn btn-success w-100 mb-3" style="white-space: normal;">Gérer les compétences</a>';
$this->content->text .= '<a href="' . $CFG->wwwroot . '/blocks/competency_iena/competency_iena_competency_mgmt.php?courseid=' . $COURSE->id . '" type="button " class="btn btn-secondary w-100 mb-3" style="white-space: normal;">Informations sur l\'APC</a>';
} else {
$this->content->text .= '<a href="' . $CFG->wwwroot . '/blocks/competency_iena/competency_iena_competencies.php?courseid=' . $COURSE->id . '" class="btn btn-primary w-100 mb-3">Mes Compétences</a>';
}
$competenceI = new block_competency_iena_competency();
$competences = $competenceI->get_competencies_by_userID($USER->id);
$nb_ok = 0;
$nb_total = count($competences);
// var_dump($competences);
foreach ($competences as $comp) {
if ($comp->proficiency == 1) {
$nb_ok++;
}
}
// $this->content->text .= "<p></p>";
if ($nb_total > 0) {
$progress_percentage = ceil($nb_ok*100/$nb_total);
$this->content->text .= "
<div class=\"progress\">
<div class=\"progress-bar\" role=\"progressbar\" style=\"width: $progress_percentage%;\" aria-valuenow=\"$nb_ok\" aria-valuemin=\"0\" aria-valuemax=\"$nb_total\">$nb_ok/$nb_total</div>
</div>
";
} else {
$progress_percentage = 0;
$this->content->text .= "
<div class=\"progress\">
<div class=\"progress-bar\" role=\"progressbar\" style=\"width: $progress_percentage%;\" aria-valuenow=\"$nb_ok\" aria-valuemin=\"0\" aria-valuemax=\"$nb_total\"></div>
</div>
";
}
// $this->content->text .= "
// <div class=\"thermo\">
// <div class=\"round_thermo\">
// <span class=\"text_round_thermo\">
// $nb_ok/$nb_total
// </span>
// </div>
// <div class=\"thermo_bar\">
// <progress class=\"progress\" max=\"$nb_total\" value=\"$nb_ok\"></progress>
// </div>
// </div>
// ";
return $this->content;
}
}
?>
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: softia
* Date: 28/03/18
* Time: 12:08
*/
namespace block_competency_iena\task;
class sync_task_iena_competency extends \core\task\scheduled_task
{
/**
* Get a descriptive name for this task (shown to admins).
*
* @return string
*/
public function get_name()
{
return "task_iena_competency";
}
public function execute()
{
global $CFG;
require_once($CFG->dirroot . '/blocks/competency_iena/entity/block_competency_iena_cron_competency.php');
$cron_test = new \block_competency_iena_cron_competency();
$cron_test->attribute_competency_iena();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: softia
* Date: 28/03/18
* Time: 12:08
*/
namespace block_competency_iena\task;
class sync_task_iena_roles extends \core\task\scheduled_task
{
/**
* Get a descriptive name for this task (shown to admins).
*
* @return string
*/
public function get_name()
{
return "task_iena_roles";
}
public function execute()
{
global $CFG;
require_once($CFG->dirroot . '/blocks/competency_iena/entity/block_competency_iena_cron_roles.php');
$cron_test = new \block_competency_iena_cron_roles();
$cron_test->attribute_roles_iena();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: softia
* Date: 28/03/18
* Time: 12:08
*/
namespace block_competency_iena\task;
class sync_task_iena_roles_complete extends \core\task\scheduled_task
{
/**
* Get a descriptive name for this task (shown to admins).
*
* @return string
*/
public function get_name()
{
return "task_iena_roles_complete";
}
public function execute()
{
global $CFG;
require_once($CFG->dirroot . '/blocks/competency_iena/entity/block_competency_iena_cron_roles.php');
$cron_test = new \block_competency_iena_cron_roles();
$cron_test->attribute_roles_iena_complete();
}
}
\ No newline at end of file
<?php
require_once('../../config.php');
// ENLEVER SI NON NECESSAIRE :
require_once('entity/block_competency_iena_competency.php');
require_once('entity/block_competency_iena_module.php');
require_once('entity/block_competency_iena_ressource.php');
require_once('entity/block_competency_iena_section.php');
require_once('entity/block_competency_iena_student.php');
require_once('entity/block_competency_iena_cron_roles.php');
require_once('entity/block_competency_iena_cron_competency.php');
require_once('view/view_competency_iena_competencies.php');
global $COURSE, $DB, $USER;
try {
$courseid = required_param('courseid', PARAM_INT);
} catch (coding_exception $e) {
}
try {
$studentid = optional_param('studentid', $USER->id, PARAM_INT);
} catch (coding_exception $e) {
}
try {
$url = new moodle_url('/blocks/competency_iena/competency_iena_competencies.php', array('courseid' => $courseid, 'studentid' => $studentid));
} catch (moodle_exception $e) {
}
$PAGE->set_pagelayout('course');
try {
$PAGE->set_url($url);
} catch (coding_exception $e) {
}
try {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
} catch (dml_exception $e) {
}
try {
require_login($course, false, NULL);
} catch (coding_exception $e) {
} catch (require_login_exception $e) {
} catch (moodle_exception $e) {
}
try {
$PAGE->set_title(get_string('title_plugin', 'block_competency_iena'));
} catch (coding_exception $e) {
}
try {
$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
} catch (coding_exception $e) {
}
try {
echo $OUTPUT->header();
} catch (coding_exception $e) {
}
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">";
/*$cron_test = new block_competency_iena_cron_roles();
$cron_test->attribute_roles_iena_complete();*/
/*$cron_test = new block_competency_iena_cron_competency();
$cron_test->attribute_competency_iena();*/
$view = new view_competency_iena_competencies();
echo $view->get_content($studentid);
try {
echo $OUTPUT->footer();
} catch (coding_exception $e) {
}
<?php
/**
* Created by PhpStorm.
* User: softia
* Date: 04/04/18
* Time: 14:59
*/
require_once('../../config.php');
// ENLEVER SI NON NECESSAIRE :
require_once('entity/block_competency_iena_competency.php');
require_once('entity/block_competency_iena_module.php');
require_once('entity/block_competency_iena_ressource.php');
require_once('entity/block_competency_iena_section.php');
require_once('entity/block_competency_iena_student.php');
require_once('entity/block_competency_iena_cron_roles.php');
require_once('entity/block_competency_iena_cron_competency.php');
require_once('entity/block_competency_iena_referentiel.php');
require_once('view/view_competency_iena_competencies.php');
global $COURSE, $DB, $USER;
$courseid = required_param('courseid', PARAM_INT);
//$studentid = optional_param('studentid',$USER->id,PARAM_INT);
$url = new moodle_url('/blocks/competency_iena/competency_iena_competencies_api.php', array('courseid' => $courseid));
$PAGE->set_pagelayout('course');
$PAGE->set_url($url);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
require_login($course, false, NULL);
if ($_POST) {
if (isset($_POST["idcompetence"])) {
$idcompetence = htmlspecialchars($_POST["idcompetence"]);
$compI = new block_competency_iena_competency();
$compI->get_competency_by_id($idcompetence);
$tab['shortname'] = $compI->shortname;
$tab['description'] = $compI->description;
$tab['id'] = $compI->id;
echo json_encode($tab);
}
if (isset($_POST["addcomp"])) {
$value = $_POST["addcomp"];
$refI = new block_competency_iena_referentiel();
$is_insert = $refI->add_competency_in_course($value[0], $value[1]);
if ($is_insert) {
echo 'true';
} else {
echo 'false';
}
}
// updateTextRef
if (isset($_POST["idref"])) {
$idref = $_POST["idref"];
$refI = new block_competency_iena_referentiel();
$value = $refI->get_info_framework_by_id($idref);
$tab['shortname'] = $value->shortname;
$tab['description'] = $value->description;
$tab['id'] = $value->id;
echo json_encode($tab);
}
if (isset($_POST["delproof"])) {
$idproof = htmlspecialchars($_POST["delproof"]);
$DB->delete_records("competency_evidence", array('id' => $idproof));
return 'true';
}
if (isset($_POST["askvalide"])) {
$idcompetence = $_POST["askidcomp"];
$iduser = $_POST["iduser"];
$status = $_POST["askvalide"];
$id_usercomp = $DB->get_record_sql('select id FROM {competency_usercomp}
WHERE competencyid = ? AND userid = ?', array($idcompetence,$iduser));
if ( $id_usercomp->id == NULL ) {
$record = new stdClass();
$record->userid = $iduser;
$record->competencyid = $idcompetence;
$record->status = $status;
$record->reviewerid = NULL;
$record->proficiency = NULL;
$record->grade = NULL;
date_default_timezone_set('Europe/Paris');
$record->timecreated = time();
$record->timemodified = time();
$record->usermodified = $iduser;
$lastinsertid = $DB->insert_record('competency_usercomp', $record, false);
var_dump($lastinsertid);
die;
} else {
$record = new stdClass();
$record->id = $id_usercomp->id;
$record->status = $status;
$DB->update_record("competency_usercomp", $record, false);
}
}
if (isset($_POST["eval_comp"])){
$eval_comp = $_POST["eval_comp"];
$iduser = $_POST["userid"];
$idcompetence = $_POST["compid"];
$eval_comp_note = $_POST["eval_comp_note"];
$eval_comp++;
$api = new \core_competency\external();
// var_dump($api::grade_competency_in_course($courseid,$iduser,$idcompetence,$eval_comp,null));
$api::grade_competency_in_course($courseid,$iduser,$idcompetence,$eval_comp,$eval_comp_note);
// si une demande d'évaluation est en cours sur cette compétence, il faut la retirer
$id_usercomp = $DB->get_record_sql('select id, status FROM {competency_usercomp}
WHERE competencyid = ? AND userid = ?', array($idcompetence,$iduser));
if ( $id_usercomp->status == 1 ) {
$record = new stdClass();
$record->id = $id_usercomp->id;
$record->status = 0;
$DB->update_record("competency_usercomp", $record, false);
}
}
}
\ No newline at end of file
<?php
require_once('../../config.php');
// ENLEVER SI NON NECESSAIRE :
require_once('entity/block_competency_iena_competency.php');
require_once('entity/block_competency_iena_module.php');
require_once('entity/block_competency_iena_ressource.php');
require_once('entity/block_competency_iena_section.php');
require_once('entity/block_competency_iena_student.php');
global $COURSE, $DB;
try {
$courseid = required_param('courseid', PARAM_INT);
} catch (coding_exception $e) {
}
try {
$url = new moodle_url('/blocks/competency_iena/competency_iena_competencies_form.php', array('courseid' => $courseid));
} catch (moodle_exception $e) {
}
//$requete = $DB->get_record_sql('SELECT course FROM {block_competency_iena} WHERE id = ?', array($courseid));
$PAGE->set_pagelayout('course');
try {
$PAGE->set_url($url);
} catch (coding_exception $e) {
}
try {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
} catch (dml_exception $e) {
}
try {
require_login($course, false, NULL);
} catch (coding_exception $e) {
} catch (require_login_exception $e) {
} catch (moodle_exception $e) {
}
try {
$PAGE->set_title(get_string('title_plugin', 'block_competency_iena'));
} catch (coding_exception $e) {
}
try {
$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
} catch (coding_exception $e) {
}
try {
echo $OUTPUT->header();
} catch (coding_exception $e) {
}
//$PAGE->requires->js("/blocks/competency_iena/js/jquery.min.js");
//$PAGE->requires->js("/blocks/competency_iena/js/file.js");
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">";
//require_once('view/view_competency_iena_unit.php');
try {
echo $OUTPUT->footer();
} catch (coding_exception $e) {
}
<?php
require_once('../../config.php');
// ENLEVER SI NON NECESSAIRE :
require_once('entity/block_competency_iena_competency.php');
require_once('entity/block_competency_iena_module.php');
require_once('entity/block_competency_iena_ressource.php');
require_once('entity/block_competency_iena_section.php');
require_once('entity/block_competency_iena_student.php');
require_once('entity/block_competency_iena_referentiel.php');
require_once('view/view_competency_iena_competencies_mgmt.php');
global $COURSE, $DB, $CFG;
try {
$courseid = required_param('courseid', PARAM_INT);
} catch (coding_exception $e) {
}
try {
$url = new moodle_url('/blocks/competency_iena/competency_iena_competencies_mgmt.php', array('courseid' => $courseid));
} catch (moodle_exception $e) {
}
//$requete = $DB->get_record_sql('SELECT course FROM {block_competency_iena} WHERE id = ?', array($courseid));
try {
$PAGE->set_url($url);
} catch (coding_exception $e) {
}
if ($_POST) {
if ($_POST['info'][0] == "delete_cpt") {
$module_id = htmlspecialchars($_POST['info'][1]);
$cpt_id = htmlspecialchars($_POST['info'][2]);
$cpt_api = new \core_competency\api();
$cpt_list = $cpt_api->remove_competency_from_course($module_id, $cpt_id);
echo $cpt_list;
}
else if ($_POST['info'][2] == "delete") {
// Suppression du lien module - compétence dans la BDD
$module_id = htmlspecialchars($_POST['info'][0]);
$competency_id = htmlspecialchars($_POST['info'][1]);
// vérification si lien module - compétence existe
try {
$data_exist = $DB->get_record_sql('select count(*) AS count FROM {competency_modulecomp} WHERE cmid=? AND competencyid =?', array($module_id, $competency_id));
} catch (dml_exception $e) {
}
//var_dump($data_exist);
if ($data_exist->count > 0) {
//$DB->get_record_sql(' delete FROM {competency_modulecomp} WHERE cmid=? AND competencyid =?' , array($module_id, $competency_id));
try {
$DB->delete_records('competency_modulecomp', array('cmid' => $module_id, 'competencyid' => $competency_id));
} catch (dml_exception $e) {
}
// vérifier si succes suppression
echo 'true';
} else {
echo 'false';
}
} // Insert or update DB
else {