Commit 9ecc8654 authored by Thomas Fradet's avatar Thomas Fradet

Initial commit

parents
# Block Groups : Moodle - Mahara
This Moodle plugin create group(s) in Mahara, based on Moodle course users. You can either create one Mahara group per Moodle course user groups.
## Authors
- Vrignaud Camille *(cvrignaud@softia.fr)*
- Lebeau Michaël *(mlebeau@softia.fr)*
- Thomas Fradet *(thomas.fradet@univ-lorraine.fr)*
## Compatibility and support
The plugin was tested in Moodle 3.3, 3.4 and 3.5.
For more information contact : support_git@softia.fr or iena-contact@univ-lorraine.fr.
## Installation
The plugin installs with the classical way but require a specific configuration to link moodle and mahara.
Installation :
- Trough the Moodle Administration section "Plugin" -> Add plugin
- Add block in edit mode
Configuration :
???
## Functionalities
By clicking a button in this block, editing teachers can create one mahara group within every student enrolled in the moodle course will become members of the mahara group. Moodle course enrolled users with the role of "teacher" and "editingteacher" will have the role of "admin" in the mahara group, other will be simple members.
After group creation, every user enrolled in this moodle cours will be able to see and click a button witch grand access to the mahara group previously created.
Alternatively, if they are user groups within the moodle cours, teacher can choose to create one mahara group per moodle course group. In this case, students and teachers will be enroll in the mahara group witch correspond to they moodle group. Warning : if one user is in two groups in moodle course, only the first will be considerated by this plugin to grand access to mahara group.
Usecase : place 3 groups with 1 teacher and n students in a moodle course and create in one click 3 mahara groups where each teacher will be able to administrate his mahara group and each student will be able to access the right group in mahara, based on the moodle group.
## Warning
This plugin is currently under development.
This plugin does not support groupments (moodle group of group) in addition to the creation of a mahara group for each moodle group. If you have groupments in moodle, choose to create on mahara group for all the moodle course participants or place the groupes in groupment 0.
In the case of generating one mahara group for each moodle group, if one user is in two groups in moodle course, only the first will be considerated by this plugin to grand access to mahara group.
This diff is collapsed.
<?php
$capabilities = array(
'block/mahara_iena:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/mahara_iena:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
)
);
?>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="blocks/mahara_iena/db" VERSION="20180710" COMMENT="XMLDB file for Moodle blocks/mahara_iena"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="block_mahara_iena" COMMENT="Table du block mahara_iena">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="course" TYPE="int" LENGTH="8" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="mahara_group_id" TYPE="int" LENGTH="8" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="moodle_group_id" TYPE="int" LENGTH="8" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
<?php
if (!defined('MOODLE_INTERNAL'))
die('Direct access to this script is forbidden.');
class block_mahara_iena_edit_form extends block_edit_form {
function specific_definition($mform) {
$mform->addElement('header','configheader', get_string('blocksettings', 'block'));
}
}
?>
This diff is collapsed.
<?php
header('HTTP/1.0 403 Forbidden');
require_once('../../config.php');
$PAGE->set_url($_SERVER['PHP_SELF']);
$PAGE->set_pagelayout('admin');
$PAGE->set_context(context_system::instance());
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('error'));
echo '<center>'.get_string('nopermissiontoshow', 'core_error').'</center>';
?>
\ No newline at end of file
<?php
$string['date_release'] = '{$a->month}.{$a->date}.{$a->year}';
$string['mahara_iena'] = 'Mahara groups';
$string['mahara_iena:addinstance'] = 'Add a new Mahara group block';
$string['mahara_iena:myaddinstance'] = 'Add a new Mahara group block to the My Moodle page';
$string['pluginname'] = 'Mahara portfolio groups';
$string['title_plugin'] = '{$a} groups';
$string['create_group'] = 'Create a {$a} group';
$string['acces_group'] = 'Accéder au groupe {$a}';
$string['create_groups_groups'] = 'Create multiple {$a} groups';
$string['this_grp'] = 'The {$a} group';
$string['just_add_grp'] = 'has been created.';
$string['mahara_grp'] = 'Go to {$a} group.';
$string['error'] = 'Erreur :';
$string['mahara_actualy'] = 'Actuellement le cours : ';
$string['link_mahara'] = 'est lier avec l\'id : ';
$string['chose_manu_grp'] = 'Choisir manuellement dans la liste des groupes mahara le groupe à lier au cours : ';
$string['send'] = 'Envoyer';
$string['back_course'] = 'Retour au cours';
$string['base_mahara'] = 'Base URL mahara';
$string['token_mahara'] = 'Token';
$string['instituion_mahara'] = 'Institution';
$string['serveur_mahara'] = 'Serveur Mahara';
$string['err_no_stud'] = 'You have to enrol users in this course before to create a {$a} group. ';
$string['course_group'] = 'Group for course';
$string['bulk_group_confirmation'] = 'Group creation succeed. ';
?>
\ No newline at end of file
<?php
$string['date_release'] = '{$a->month}.{$a->date}.{$a->year}';
$string['mahara_iena'] = 'Groupes Mahara';
$string['mahara_iena:addinstance'] = 'Ajouter un block Groupes Mahara';
$string['mahara_iena:myaddinstance'] = 'Ajouter un block Groupes Mahara sur ma page';
$string['pluginname'] = 'Groupes portfolio Mahara';
$string['title_plugin'] = 'Groupes {$a}';
$string['create_group'] = 'Créer un groupe dans {$a}';
$string['acces_group'] = 'Accéder au groupe {$a}';
$string['create_groups_groups'] = 'Créer plusieurs groupes {$a}';
$string['this_grp'] = 'Le groupe {$a}';
$string['just_add_grp'] = 'a bien été créé. ';
$string['mahara_grp'] = 'Accéder au groupe {$a}.';
$string['error'] = 'Erreur : ';
$string['mahara_actualy'] = 'Actuellement le cours : ';
$string['link_mahara'] = 'est lié avec le groupe : ';
$string['chose_manu_grp'] = 'Choisir manuellement dans la liste des groupes mahara le groupe à lier au cours : ';
$string['send'] = 'Lié au cours';
$string['back_course'] = 'Retour au cours';
$string['base_mahara'] = 'Base URL mahara';
$string['token_mahara'] = 'Token';
$string['instituion_mahara'] = 'Institution';
$string['serveur_mahara'] = 'Serveur Mahara';
$string['err_no_stud'] = 'Vous devez inscrire des utilisateurs dans le cours avant de créer un groupe {$a}. ';
$string['course_group'] = 'Groupe du cours';
$string['bulk_group_confirmation'] = 'Les groupes ont bien été créés. ';
?>
\ No newline at end of file
<?php
require_once('../../config.php');
require_once ('entity/block_mahara_iena_connexion.php');
global $COURSE, $DB, $USER, $CFG;
$courseid = required_param('courseid', PARAM_INT);
$studentid = optional_param('studentid',$USER->id,PARAM_INT);
$url = new moodle_url('/blocks/mahara_iena/mahara_iena.php',array('courseid' => $courseid, 'studentid' => $studentid));
$PAGE->set_pagelayout('course');
$PAGE->set_url($url);
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
require_login($course, false, NULL);
if (!has_capability('moodle/course:update', $context = context_course::instance($courseid), $USER->id)) {
header("Location: {$_SERVER['HTTP_REFERER']}");
exit;
}
$PAGE->set_title(get_string('title_plugin', 'block_mahara_iena', $CFG->mahara_alias));
$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
echo $OUTPUT->header();
// echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">";
$connexion = new block_mahara_iena_connexion($CFG->wstoken,$CFG->base_mahara);
//Get all students
$course_ctx = context_course::instance($course->id);
$students = get_enrolled_users($course_ctx);
$usersTab = array();
$maharaUsers = $connexion->getMaharaUsers();
//Here we check by email, if the student have the same email into mahara and moodle he is add to group
if (count($students) == 0) {
echo "<div class=\"alert alert-warning\" role=\"alert\">"
.get_string('err_no_stud', 'block_mahara_iena', $CFG->mahara_alias)
."</div>";
} else {
foreach ($maharaUsers->users as $muser) {
foreach ($students as $student) {
if ($student->email == $muser->email){
$role = "member";
//Each students is admin
if (has_capability('moodle/course:update', $context = context_course::instance($COURSE->id), $student->id)) {
$role = "admin";
}
array_push($usersTab,array(
'id' => $muser->id,
'username' => $muser->username,
'role' => $role,
));
break;
}
}
}
//All params used for mahara_group_create_groups her we can add/change some lines
$params = array (
'groups' =>
array (
0 =>
array (
'name' => get_string('course_group', 'block_mahara_iena') . " " . $COURSE->shortname,
'description' => get_string('course_group', 'block_mahara_iena') . " " . $COURSE->shortname,
'grouptype' => 'course',
'request' => true,
'public' => false,
'institution' => $CFG->instution_mahara,
'members' =>
$usersTab
)
)
);
//Convert arrays into string for send to mahara api
$params = http_build_query($params);
$function = "mahara_group_create_groups";
$resultPost = $connexion->httpPost($params, $connexion->create_url($function));
// '@' is use because json_decode some time cause fatal error
$data = @json_decode($resultPost);
$result = $DB->get_records_sql('SELECT * FROM {block_mahara_iena} WHERE course = ?', array($COURSE->id));
// IF json_decode fail we stop all
if ($data == null){
echo 'error';
} else {
// if $data is array the api call is done (OK)
if (is_array($data)) {
// if the query is empty we add new line
if (!$result) {
$record = new stdClass();
$record->course = $COURSE->id;
$record->mahara_group_id = $data[0]->id;
$record->moodle_group_id = 0;
$r = $DB->insert_record('block_mahara_iena',$record,false);
if ( substr($CFG->base_mahara, -1) !== "/" ) {
$base = $CFG->base_mahara . "/";
} else {
$base = $CFG->base_mahara;
}
echo "<div class=\"alert alert-success\" role=\"alert\">"
.get_string('this_grp', 'block_mahara_iena', $CFG->mahara_alias)." "
.$COURSE->shortname." "
.get_string('just_add_grp', 'block_mahara_iena')." "
."<a target=\"_blank\" href='".$base."group/view.php?id=".$data[0]->id."'>"
.get_string('mahara_grp', 'block_mahara_iena', $CFG->mahara_alias)."</a></div>";
}
// If the query is not empty we leave the choice to set the "code" value
} elseif ($data->error) {
echo "<div class=\"alert alert-danger\" role=\"alert\"> ".get_string('error', 'block_mahara_iena').$data->error_message."</div>";
}
}
}
echo "<p><a href=\"".$CFG->wwwroot."/course/view.php?id=".$COURSE->id." \" class=\"btn btn-primary\" role=\"button\">".get_string('back_course', 'block_mahara_iena')."</a></p>";
echo $OUTPUT->footer();
<?php
require_once('../../config.php');
require_once ('entity/block_mahara_iena_connexion.php');
global $COURSE, $DB, $USER, $CFG;
$courseid = required_param('courseid', PARAM_INT);
$studentid = optional_param('studentid',$USER->id,PARAM_INT);
$url = new moodle_url('/blocks/mahara_iena/mahara_iena_groups.php',array('courseid' => $courseid, 'studentid' => $studentid));
$PAGE->set_pagelayout('course');
$PAGE->set_url($url);
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
require_login($course, false, NULL);
if (!has_capability('moodle/course:update', $context = context_course::instance($courseid), $USER->id)) {
header("Location: {$_SERVER['HTTP_REFERER']}");
exit;
}
$PAGE->set_title(get_string('title_plugin', 'block_mahara_iena', $CFG->mahara_alias));
$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
echo $OUTPUT->header();
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">";
$connexion = new block_mahara_iena_connexion($CFG->wstoken,$CFG->base_mahara);
//Get all students
$course_ctx = context_course::instance($course->id);
$students = get_enrolled_users($course_ctx);
if (count($students) == 0) {
echo "<div class=\"alert alert-warning\" role=\"alert\">"
.get_string('err_no_stud', 'block_mahara_iena', $CFG->mahara_alias)
."</div>";
} else {
$groups = groups_get_all_groups($COURSE->id);
$maharaUsers = $connexion->getMaharaUsers();
$mahara_groups = array();
$name_groups = array();
foreach ($groups as $group) {
$usersTab = array();
$members = groups_get_members($group->id);
if ( count($members) == 0 ) {
continue;
}
foreach ($members as $member) {
$course_roles = get_user_roles($course_ctx, $member->id, false);
$role = "member";
foreach ($course_roles as $course_role) {
if ($course_role->shortname == "teacher" || $course_role->shortname == "editingteacher") {
$role = "admin";
break;
}
}
foreach ($maharaUsers->users as $muser) {
if ($member->email == $muser->email){
array_push($usersTab,array(
'id' => $muser->id,
'username' => $muser->username,
'role' => $role,
));
break;
}
}
}
if ( count($usersTab) == 0 ) {
continue;
}
array_push($mahara_groups, array(
'name' => get_string('course_group', 'block_mahara_iena') . " " . $COURSE->shortname . " – " . $group->name,
'description' => get_string('course_group', 'block_mahara_iena') . " " . $COURSE->shortname . " – " . $group->name,
'grouptype' => 'course',
'request' => true,
'public' => false,
'institution' => $CFG->instution_mahara,
'members' =>
$usersTab
));
array_push($name_groups, array(
"group_id" => $group->id,
"group_name" => get_string('course_group', 'block_mahara_iena') . " " . $COURSE->shortname . " – " . $group->name,
));
}
// var_dump($name_groups);
// die;
if ( count($mahara_groups) == 0 ) {
echo "<div class=\"alert alert-warning\" role=\"alert\"><p><strong>Erreur : tous les groupes du cours sont vides. </strong></p><p>Pour utiliser cette fonctionnalité, il faut au préalable créer des groupes dans le cours et y ajouter des étudiants ou des enseignants.</p></div>";
} else {
$params = array(
'groups' => $mahara_groups
);
$params = http_build_query($params);
$function = "mahara_group_create_groups";
$murl = $connexion->create_url($function);
$resultPost = $connexion->httpPost($params, $murl);
// '@' is use because json_decode some time cause fatal error
$data = @json_decode($resultPost);
// var_dump($data);
$result = $DB->get_records_sql('SELECT * FROM {block_mahara_iena} WHERE course = ?', array($COURSE->id));
// IF json_decode fail we stop all
if ($data == null){
echo 'error';
} else {
// if $data is array the api call is done (OK)
if (is_array($data)) {
// if the query is empty we add new line
if (!$result) {
echo "<pre>";
$save = array();
foreach ($data as $value) {
$record = new stdClass();
$record->course = $COURSE->id;
$record->mahara_group_id = $value->id;
$record->moodle_group_id = 0;
foreach ($name_groups as $name_group) {
// var_dump($name_group["group_name"]);
// var_dump($name_group["group_id"]);
// var_dump($value->name);
if ( $value->name == $name_group["group_name"] ) {
$record->moodle_group_id = $name_group["group_id"];
break;
}
}
array_push($save, $record);
}
echo "</pre>";
$DB->insert_records('block_mahara_iena',$save,false);
if ( substr($CFG->base_mahara, -1) !== "/" ) {
$base = $CFG->base_mahara . "/";
} else {
$base = $CFG->base_mahara;
}
echo "<div class=\"alert alert-success\" role=\"alert\">"
.get_string('bulk_group_confirmation', 'block_mahara_iena')
."</div>";
}
// If the query is not empty we leave the choice to set the "code" value
} elseif ($data->error) {
echo "<div class=\"alert alert-danger\" role=\"alert\"> ".get_string('error', 'block_mahara_iena').$data->error_message."</div>";
}
}
}
}
echo "<p><a href=\"".$CFG->wwwroot."/course/view.php?id=".$COURSE->id." \" class=\"btn btn-primary\" role=\"button\">".get_string('back_course', 'block_mahara_iena')."</a></p>";
echo $OUTPUT->footer();
<?php
require_once('../../config.php');
require_once ('entity/block_mahara_iena_connexion.php');
global $COURSE, $DB, $USER, $CFG;
$courseid = required_param('courseid', PARAM_INT);
$url = new moodle_url('/blocks/mahara_iena/mahara_iena_groups_all.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 (!has_capability('moodle/course:update', $context = context_course::instance($courseid), $USER->id)) {
header("Location: {$_SERVER['HTTP_REFERER']}");
exit;
}
$PAGE->set_title(get_string('title_plugin', 'block_mahara_iena', $CFG->mahara_alias));
$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
echo $OUTPUT->header();
/* Crée dans Mahara un groupe pour chaque groupe existant dans le cours
* Si au départ, un seul groupe avait été créé pour tout le cours, alors maintenant
* il y en aura plusieurs (si il y a plusieurs groupe).
*/
if ( $_GET['create_all_groups'] ) {
$content = "";
/* tous les groupes du cours */
$mo_course_groups = groups_get_all_groups($COURSE->id, 0, 0);
/* toutes les association cours - groupe moodle - groupe mahara */
$mo_ma_groups = $DB->get_records_sql('SELECT * FROM {block_mahara_iena} WHERE course = ?', array($COURSE->id));
/* stockera les nouvelles associations */
$created_associations = [];
/* en cas d'erreur pour un message à la fin */
$errors = 0;
$block_mahara_iena_connexion = new block_mahara_iena_connexion($CFG->wstoken,$CFG->base_mahara);
/* pour chaque groupe du cours */
foreach ($mo_course_groups as $mo_course_group) {
$mo_ma_exists = false;
/* pour chaque groupe déjà enregistré et donc existant */
foreach ($mo_ma_groups as $mo_ma_group) {
/* si le cours est déjà dans la base */
if ( $mo_course_group->id == $mo_ma_group->moodle_group_id ) {
$block_mahara_iena_connexion->ensure_user_is_mahara_group_member_new($USER, $mo_ma_group->mahara_group_id, null);
$mo_ma_exists = true;
}
}
/* si le cours n'est pas dans la base */
if ( $mo_ma_exists === false ) {
/* stocker le nom des groupes pour un message de confirmation */
$succeed = $block_mahara_iena_connexion->create_mahara_group($mo_course_group, $USER);
if ( $succeed == true ) {
$created_associations[] = $mo_course_group->name;
} else {
$errors += 1;
}
}
}
/* afficher le nom des groupes créés pour une association pour un message de confirmation */
if ( count($created_associations) !== 0 ) {
$content .= "<div class='alert alert-success'><p>Des groupes ont été créés dans " . $CFG->mahara_alias . " : </p>
<ul style='margin-left: 1.2rem;'>";
foreach ($created_associations as $created_association) {
$content .= '<li>Groupe : "' . $created_association . '"</li>';
}
$content .= "</ul></div>";
} else {
if ( $errors === true ) {
$content .= "<div class='alert alert-danger'><p>Une ou plusieurs erreurs se sont produites pendant la création des groupes sur " . $CFG->mahara_alias . ".</p></div>";
} else {
$content .= "<div class='alert alert-secondary'><p>Aucun groupe n'a été créé dans " . $CFG->mahara_alias . ". Il doivent déjà exister. </p></div>";
}
}
$content .= "<a class='btn btn-primary' href='" . $CFG->wwwroot . "/course/view.php?id=" . $_GET['courseid'] . "'>Retour au cours</a>";
echo $content;
} else {
// ceci ne devrait plus être utilisé, c'était dans le cas où on voulait inscrire un ens. à tous les groupes existant, mais ceci est assuré par le bouton qui créé tous les groupes et y inscrit l'ens. donc ce n'est plus forcément nécessaire. le bouton pour simplement s'inscrire à tous les groupes a été supprimé.
// cependant, un enseignant pourrait vouloir s'inscrire à tous les groupes sans pour autant chercher à les créer donc il faudrait rajouter un bouton alternatif ; actuellement, l'ens. ne semble pas inscrit aux groupes qui existent déjà
// idéalement, un ens. devrait pouvoir choisir de créer tous les groupes sans forcément s'y inscrire et de s'inscrire et se désinscrire de tous les groupes (attention, il est préférable de ne pas laisser de groupes abandonnés donc pas de désinscription si l'ens. est le seul membre restant (et même le seul parmi les admin du groupe)).
// obtenir l'utilisateur
// checker qu'il est enseignant ("editingteacher")
// récupérer tous les groupes mahara liés au cours
// pour chaque groupe mahara lié au cours
// récupérer si l'utilisateur est membre du groupe mahara
// si non membre du groupe mahara : update group pour inscrire
// message de confirmation ou d'erreur
$result = $DB->get_records_sql('SELECT * FROM {block_mahara_iena} WHERE course = ?', array($COURSE->id));
$connexion = new block_mahara_iena_connexion($CFG->wstoken,$CFG->base_mahara);
$errors = 0;
$succeed = 0;
foreach ($result as $record) {
$success = $connexion->ensure_user_is_mahara_group_member($USER, $record->mahara_group_id);
if ( !$success ) {
$errors += 1;
} else {
$succeed += 1;
}
}
$content = "";
if ( $errors > 0 ) {
$content .= '<div class="alert alert-danger">L\'inscription a échoué dans '.$errors.' groupes sur.</div>';
}
$content .= '<div class="alert alert-success">L\'inscription a été effectuée dans '.$succeed.' groupes.</div>';
$content .= "<a href=\"".$CFG->wwwroot."/course/view.php?id=".$COURSE->id." \" class=\"btn btn-primary\" role=\"button\">".get_string('back_course', 'block_mahara_iena')."</a>";
echo $content;
}
echo $OUTPUT->footer();
<?php
require_once('../../config.php');
require_once ('entity/block_mahara_iena_connexion.php');
global $COURSE, $DB, $USER, $CFG;
$courseid = required_param('courseid', PARAM_INT);
$studentid = optional_param('studentid',$USER->id,PARAM_INT);
$url = new moodle_url('/blocks/mahara_iena/mahara_iena_link.php',array('courseid' => $courseid, 'studentid' => $studentid));
$PAGE->set_pagelayout('course');
$PAGE->set_url($url);
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
require_login($course, false, NULL);
if ($_GET['mahara_group']){
$mnetauth = get_auth_plugin('mnet');
$group_url = "/group/view.php?id=".$_GET['mahara_group'];
$url = $mnetauth->start_jump_session($CFG->iena_mahara, $group_url);
if (empty($url)) {
print_error('DEBUG: Jump session was not started correctly or blank URL returned.'); // TODO: errors
}
redirect($url);