Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
iena
iena-course-format
Commits
b221c63a
Commit
b221c63a
authored
Oct 25, 2021
by
Myriam Delaruelle
Browse files
Merge branch 'dev'
parents
8962549c
15e15638
Changes
34
Expand all
Hide whitespace changes
Inline
Side-by-side
amd/build/header.js
0 → 100644
View file @
b221c63a
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Handle add/remove competency links.
*
* @module format_iena/suivi
* @package format_iena
* @copyright 2021 Myriam Delaruelle
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define
([
'
jquery
'
,
'
core/ajax
'
,
'
core/str
'
],
function
(
$
,
ajax
,
str
)
{
return
{
registerHeader
:
function
(){
$
(
"
#button-collapse
"
).
click
(
function
(){
if
(
$
(
"
#summary-wrapper
"
).
hasClass
(
'
collapsed
'
)){
$
(
"
#summary-wrapper
"
).
animate
({
"
max-height
"
:
'
7rem
'
},
"
slow
"
);
var
message
=
str
.
get_string
(
'
displayInfos
'
,
'
format_iena
'
);
$
.
when
(
message
).
done
(
function
(
localizedEditString
)
{
$
(
"
#button-collapse
"
).
text
(
localizedEditString
);
});
}
else
{
var
height
=
$
(
"
#summary-collapse
"
).
css
(
"
height
"
);
$
(
"
#summary-wrapper
"
).
animate
({
"
max-height
"
:
height
},
"
slow
"
);
var
message
=
str
.
get_string
(
'
hideInfos
'
,
'
format_iena
'
);
$
.
when
(
message
).
done
(
function
(
localizedEditString
)
{
$
(
"
#button-collapse
"
).
text
(
localizedEditString
);
});
}
$
(
"
#summary-wrapper
"
).
toggleClass
(
"
collapsed
"
);
})
}
}
});
amd/build/suivi-table.js
0 → 100644
View file @
b221c63a
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Handle add/remove competency links.
*
* @module format_iena/suivi-table
* @package format_iena
* @copyright 2021 Myriam Delaruelle
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define
([
'
jquery
'
],
function
(
$
)
{
var
all_selected
=
false
;
return
{
registerSelectAll
:
function
(){
all_selected
=
false
;
$
(
'
#iena-select-all
'
).
on
(
'
click
'
,
function
(
e
){
select_all_studs
(
e
);
});
}
}
function
select_all_studs
(
e
)
{
all_selected
=!
all_selected
;
var
counter
=
0
;
var
checks
=
document
.
querySelectorAll
(
"
#table-body tr
"
);
for
(
var
i
=
0
;
i
<
checks
.
length
;
i
++
)
{
if
(
checks
[
i
].
style
.
display
!=
"
none
"
||
all_selected
)
{
var
box
=
checks
[
i
].
querySelector
(
"
input[type='checkbox']
"
);
box
.
checked
=
all_selected
;
counter
++
;
}
}
}
});
amd/build/suivi.js
0 → 100644
View file @
b221c63a
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Handle add/remove competency links.
*
* @module format_iena/suivi
* @package format_iena
* @copyright 2021 Myriam Delaruelle
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define
([
'
jquery
'
,
'
core/ajax
'
,
'
core/templates
'
,
'
core/str
'
],
function
(
$
,
ajax
,
templates
,
str
)
{
var
all_selected
=
false
;
var
data
=
[];
return
{
registerFilters
:
function
(){
$
(
"
#group-select
"
).
on
(
'
change
'
,
function
(
e
){
changeGroup
();
});
},
registerSubmit
:
function
(
infos
){
data
=
infos
;
$
(
"
#id_submit_iena
"
).
on
(
'
click
'
,
function
(
e
){
triggerAction
(
e
);
});
$
(
"
#section-select
"
).
on
(
'
change
'
,
function
(){
changeSection
();
});
$
(
"
#filter-select
"
).
on
(
'
change
'
,
function
(){
changeCompletion
();
});
$
(
"
#symbol-select
"
).
on
(
'
change
'
,
function
(){
changeCompletion
();
});
changeSection
();
/*calcPercentage(data);
changeCompletion();*/
}
}
function
initHeaders
(){
var
nb_counts
=
$
(
"
.th-rotate
"
).
length
;
$
(
"
.th-rotate
"
).
each
(
function
(
index
,
element
){
$
(
element
).
css
(
"
zIndex
"
,
nb_counts
-
index
);
})
}
function
getCompleteUrl
(){
url
=
window
.
location
.
search
;
urlParams
=
new
URLSearchParams
(
url
);
courseid
=
urlParams
.
get
(
'
courseid
'
);
groupid
=
$
(
"
#group-select
"
).
val
();
sectionid
=
$
(
"
#section-select
"
).
val
();
filter
=
$
(
"
#symbol-select
"
).
val
()
+
$
(
"
#filter-select
"
).
val
();
completeUrl
=
'
suivi_unit.php?courseid=
'
+
courseid
;
if
(
sectionid
){
completeUrl
+=
'
§ionid=
'
+
sectionid
;
}
if
(
groupid
){
completeUrl
+=
"
&groupid=
"
+
groupid
;
}
if
(
filter
){
completeUrl
+=
"
&filter=
"
+
filter
;
}
return
completeUrl
;
}
function
changeGroup
(){
completeUrl
=
getCompleteUrl
();
loadMessage
(
"
loading
"
);
$
.
ajax
({
url
:
completeUrl
,
data
:
{
action
:
'
test
'
},
type
:
'
post
'
,
success
:
function
(
request
)
{
console
.
log
(
JSON
.
parse
(
request
));
data
=
calcPercentage
(
JSON
.
parse
(
request
));
changeCompletion
();
//reloadTable(JSON.parse(request));
}
});
}
function
changeCompletion
(){
symbol
=
$
(
"
#symbol-select
"
).
val
();
filter
=
$
(
"
#filter-select
"
).
val
();
data
.
count_results
=
0
;
for
(
var
i
=
0
;
i
<
data
.
students
.
length
;
i
++
){
if
(
symbol
==
"
<
"
){
if
(
data
.
students
[
i
].
percentage
<=
filter
){
data
.
count_results
++
;
data
.
students
[
i
].
visible
=
true
;
}
else
{
data
.
students
[
i
].
visible
=
false
;
}
}
else
if
(
symbol
==
"
>
"
){
if
(
data
.
students
[
i
].
percentage
>=
filter
){
data
.
count_results
++
;
data
.
students
[
i
].
visible
=
true
;
}
else
{
data
.
students
[
i
].
visible
=
false
;
}
}
else
{
if
(
data
.
students
[
i
].
percentage
==
filter
){
data
.
count_results
++
;
data
.
students
[
i
].
visible
=
true
;
}
else
{
data
.
students
[
i
].
visible
=
false
;
}
}
}
reloadTable
(
data
);
}
//on va devoir calculer le pourcentage, check la completion et reload la table à chaque fois
function
changeSection
(){
loadMessage
(
"
loading
"
);
sectionid
=
$
(
"
#section-select
"
).
val
();
data
.
count_results
=
0
;
for
(
var
i
=
0
;
i
<
data
.
modules
.
length
;
i
++
){
if
(
data
.
modules
[
i
].
section
==
sectionid
||
sectionid
==
0
){
data
.
modules
[
i
].
visible
=
true
;
data
.
count_results
++
;
for
(
var
j
=
0
;
j
<
data
.
students
.
length
;
j
++
){
var
prog
=
data
.
students
[
j
].
progress
.
find
(
progress
=>
progress
.
idmodule
===
data
.
modules
[
i
].
id
);
prog
.
visible
=
true
;
}
}
else
{
data
.
modules
[
i
].
visible
=
false
;
for
(
var
j
=
0
;
j
<
data
.
students
.
length
;
j
++
){
data
.
students
[
j
].
progress
.
find
(
progress
=>
progress
.
idmodule
===
data
.
modules
[
i
].
id
).
visible
=
false
;
}
}
}
if
(
data
.
count_results
==
0
){
reloadTable
(
data
);
}
else
{
data
=
calcPercentage
(
data
);
changeCompletion
();
//reloadTable(data);
}
//reloadTable(data);
}
function
loadMessage
(
type
){
console
.
log
(
"
on load
"
);
if
(
type
==
"
loading
"
){
var
message
=
str
.
get_string
(
'
loadingResults
'
,
'
format_iena
'
);
}
else
if
(
type
==
"
error
"
){
var
message
=
str
.
get_string
(
'
errorLoadingResults
'
,
'
format_iena
'
);
}
$
.
when
(
message
).
done
(
function
(
localizedEditString
)
{
$
(
"
#partial-table
"
).
html
(
"
<div class='alert alert-primary' role='alert'>
"
+
localizedEditString
+
"
</div>
"
);
});
}
function
reloadTable
(
params
){
console
.
log
(
params
);
url
=
getCompleteUrl
();
templates
.
render
(
'
format_iena/suivi-table
'
,
params
)
.
done
(
function
(
html
,
js
){
console
.
log
(
"
done done
"
);
$
(
"
#partial-table
"
).
html
(
html
);
templates
.
runTemplateJS
(
js
);
window
.
history
.
pushState
(
'
suivi
'
,
""
,
url
);
initHeaders
();
})
.
fail
(
function
(){
loadMessage
(
"
error
"
);
});
}
function
getSelectedStudents
(){
var
selectedChecks
=
$
(
"
#table-body input:checked
"
);
var
students
=
[];
for
(
var
i
=
0
;
i
<
selectedChecks
.
length
;
i
++
){
students
.
push
(
selectedChecks
[
i
].
value
);
}
return
students
;
}
//Si on veut envoyer un message à tout le monde on ajoute deux champs cachés :
//La liste des étudiants (array d'id)
//L'url de retour pour revenir sur le tableau de suivi
function
triggerAction
(
e
){
value
=
$
(
"
#select-actions-suivi-iena
"
).
val
();
if
(
value
==
"
msg
"
){
url
=
window
.
location
.
search
;
urlParams
=
new
URLSearchParams
(
url
);
courseid
=
urlParams
.
get
(
'
courseid
'
);
students
=
getSelectedStudents
();
var
form
=
$
(
"
#form_send_message_iena
"
);
form
.
attr
(
"
action
"
,
"
send_message.php?courseid=
"
+
courseid
);
var
field
=
$
(
"
<input></input>
"
);
field
.
attr
(
"
type
"
,
"
hidden
"
);
field
.
attr
(
"
name
"
,
"
students
"
);
field
.
attr
(
"
value
"
,
students
.
toString
());
form
.
append
(
field
);
var
fieldUrl
=
$
(
"
<input></input>
"
);
fieldUrl
.
attr
(
"
type
"
,
"
hidden
"
);
fieldUrl
.
attr
(
"
name
"
,
"
back_url
"
);
fieldUrl
.
attr
(
"
value
"
,
url
);
form
.
append
(
fieldUrl
);
$
(
document
.
body
).
append
(
form
);
form
.
submit
();
}
else
if
(
value
==
"
download
"
){
table_download
(
data
);
}
}
function
slug_it
(
str
)
{
return
str
.
toString
().
toLowerCase
().
trim
()
.
replace
(
/
\s
+/g
,
'
-
'
)
/* Replace spaces with - */
.
replace
(
/&/g
,
'
-and-
'
)
/* Replace & with 'and' */
.
replace
(
/
[^\w\-]
+/g
,
''
)
/* Remove all non-word chars */
.
replace
(
/
\-\-
+/g
,
'
-
'
);
/* Replace multiple - with single - */
}
function
padLeft
(
date
){
return
String
(
date
).
length
>
1
?
date
:
'
0
'
+
date
;
}
function
table_download
()
{
var
students
=
getSelectedStudents
();
var
csvContent
=
"
data:text/csv;charset=utf-8,
"
;
var
head
=
[
'
Moodle_id
'
,
'
Prénom
'
,
'
Nom
'
,
'
Groupe
'
,
'
Complétion (en %)
'
];
data
.
active_section_id
=
$
(
"
#section-select
"
).
val
();
for
(
var
m
=
0
;
m
<
data
.
modules
.
length
;
m
++
)
{
if
(
data
.
active_section_id
!=
data
.
modules
[
m
].
section
&&
data
.
active_section_id
!=
0
)
{
continue
;
}
head
.
push
(
'
"
'
+
data
.
modules
[
m
].
displayname
.
replace
(
'
,
'
,
''
)
+
'
"
'
);
}
csvContent
+=
head
.
join
(
"
,
"
);
csvContent
+=
"
\n
"
;
/* Pour chaque étudiant */
for
(
var
s
=
0
;
s
<
data
.
students
.
length
;
s
++
)
{
if
(
students
.
includes
(
data
.
students
[
s
].
id
)){
var
arr_cpl
=
[];
/* Pour chaque activité du cours */
var
activities_nbr
=
0
;
var
done_activities_nbr
=
0
;
for
(
var
mod
=
0
;
mod
<
data
.
modules
.
length
;
mod
++
)
{
/* Si le module n'est pas dans la section actuellement filtrée */
if
(
data
.
active_section_id
!=
data
.
modules
[
mod
].
section
&&
data
.
active_section_id
!=
0
)
{
continue
;
}
var
stud_progress
=
data
.
students
[
s
].
progress
/* Si l'étudiant n'a pas de progres*/
if
(
stud_progress
.
length
==
0
)
{
arr_cpl
.
push
(
0
);
}
else
{
// var prog = 0;
/* Pour chaque trace d'achèvement */
var
cpl
=
0
;
for
(
var
i
=
0
;
i
<
stud_progress
.
length
;
i
++
)
{
/* Quand l'index de progression correspond à l'id du module */
if
(
data
.
modules
[
mod
].
id
==
stud_progress
[
i
].
idmodule
)
{
cpl
=
stud_progress
[
i
].
completionstate
;
if
(
cpl
==
3
)
{
cpl
=
0.5
;
cpl
=
'
"
'
+
cpl
.
toLocaleString
()
+
'
"
'
;
}
}
}
if
(
cpl
==
1
||
cpl
==
2
)
{
done_activities_nbr
++
;
}
arr_cpl
.
push
(
cpl
);
}
activities_nbr
++
;
}
var
perc
=
Math
.
round
(
100
*
100
*
done_activities_nbr
/
activities_nbr
)
/
100
;
var
groups
=
'
"
'
;
active_group_id
=
$
(
'
#group-select
'
).
val
();
data
.
active_group_name
=
$
(
'
#group-select
'
).
find
(
'
option:selected
'
).
html
()
if
(
data
.
active_group_name
!=
""
&&
active_group_id
!=
0
)
{
groups
+=
data
.
active_group_name
.
replace
(
'
"
'
,
''
);
}
else
{
groups
+=
data
.
students
[
s
].
groups
.
replace
(
'
"
'
,
''
);
}
groups
+=
'
"
'
;
var
arr
=
[
data
.
students
[
s
].
id
,
data
.
students
[
s
].
firstname
,
data
.
students
[
s
].
lastname
,
groups
,
'
"
'
+
perc
.
toLocaleString
()
+
'
"
'
,
arr_cpl
];
var
dataString
=
arr
.
join
(
"
,
"
);
csvContent
+=
dataString
+
"
\n
"
;
}
}
var
encodedUri
=
encodeURI
(
csvContent
);
var
section_name
=
data
.
active_section_id
;
if
(
section_name
==
0
)
{
section_name
=
"
cours-complet
"
;
}
else
{
section_name
=
slug_it
(
$
(
'
#section-select
'
).
find
(
'
option:selected
'
).
html
()).
substring
(
0
,
20
);
}
var
d
=
new
Date
;
month
=
d
.
getMonth
()
+
1
;
date
=
d
.
getFullYear
()
+
"
.
"
+
padLeft
(
month
)
+
"
.
"
+
padLeft
(
d
.
getDate
())
+
"
-
"
+
padLeft
(
d
.
getHours
())
+
"
.
"
+
padLeft
(
d
.
getMinutes
())
+
"
.
"
+
padLeft
(
d
.
getSeconds
());
var
link
=
document
.
createElement
(
"
a
"
);
link
.
setAttribute
(
"
href
"
,
encodedUri
);
link
.
setAttribute
(
"
download
"
,
"
report-
"
+
section_name
+
"
-
"
+
date
+
"
.csv
"
);
document
.
body
.
appendChild
(
link
);
link
.
click
();
document
.
body
.
removeChild
(
link
);
}
//Pour chaque module non caché, on va regarder pour chaque étudiant
function
calcPercentage
(
data
){
console
.
log
(
data
);
for
(
var
i
=
0
;
i
<
data
.
students
.
length
;
i
++
)
{
data
.
students
[
i
].
percentage
=
0
;
var
done
=
0
;
var
nb_modules
=
0
;
for
(
var
j
=
0
;
j
<
data
.
students
[
i
].
progress
.
length
;
j
++
){
if
(
data
.
modules
.
find
(
module
=>
module
.
id
===
data
.
students
[
i
].
progress
[
j
].
idmodule
).
visible
){
nb_modules
++
;
if
(
data
.
students
[
i
].
progress
[
j
].
completionstate
==
1
||
data
.
students
[
i
].
progress
[
j
].
completionstate
==
2
){
done
++
;
}
}
}
data
.
students
[
i
].
percentage
=
Math
.
floor
(
100
*
done
/
nb_modules
);
}
return
data
;
//reloadTable(data);
}
});
classes/task/sync_task_iena_message.php
View file @
b221c63a
...
...
@@ -51,10 +51,13 @@
public
function
execute
()
{
global
$CFG
;
mtrace
(
"IENA notifications task started"
);
require_once
(
$CFG
->
dirroot
.
'/course/format/iena/entity/course_format_iena_cron_action.php'
);
$cron_test
=
new
\
course_format_iena_cron_action
();
// echo 'send message start';
$cron_test
->
cron_message
();
mtrace
(
"IENA notifications task completed"
);
// echo 'send message stop';
}
...
...
course-header.css
View file @
b221c63a
...
...
@@ -212,4 +212,3 @@
db/install.xml
View file @
b221c63a
...
...
@@ -3,7 +3,7 @@
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<!--
<TABLES>
<TABLE NAME="format_iena" COMMENT="Default comment for format_iena, please edit me">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
...
...
@@ -21,5 +21,5 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</TABLES>
-->
</XMLDB>
\ No newline at end of file
db/tasks.php
View file @
b221c63a
...
...
@@ -37,15 +37,7 @@
$tasks
=
array
(
// array(
// 'classname' => 'format_iena\task\sync_task_iena_hide',
// 'blocking' => 0,
// 'minute' => '*/5',
// 'hour' => '*',
// 'day' => '*',
// 'month' => '*',
// 'dayofweek' => '*'
// ),
array
(
'classname'
=>
'format_iena\task\sync_task_iena_message'
,
'blocking'
=>
0
,
...
...
db/upgrade.php
0 → 100644
View file @
b221c63a
<?php
function
xmldb_format_iena_upgrade
(
$oldversion
)
{
global
$CFG
,
$DB
;
$dbman
=
$DB
->
get_manager
();
$result
=
TRUE
;
if
(
$oldversion
<
2021220900
)
{
//Support for old versions: we copy format options to the course_format_options table
try
{
$sections
=
$DB
->
get_records_sql
(
'select * FROM {format_iena}'
);
}
catch
(
dml_exception
$e
)
{
echo
"Aucun cours avec le format hybride dans la base"
;