Merge branch '1.11.x' of github.com:chamilo/chamilo-lms into 1.11.x

remotes/angel/1.11.x
Yannick Warnier 9 years ago
commit 454b6f75e3
  1. 98
      main/admin/teachers_time_by_session_report.php
  2. 135
      main/admin/user_edit.php
  3. 1
      main/inc/lib/api.lib.php
  4. 4
      main/inc/lib/usermanager.lib.php
  5. 7
      main/mySpace/works_in_session_report.php
  6. 22
      main/template/default/admin/teacher_time_report.tpl
  7. 29
      main/template/default/admin/teachers_time_by_session_report.tpl
  8. 0
      main/template/default/my_space/works_in_session_report.tpl
  9. 12
      main/work/work.lib.php

@ -5,6 +5,10 @@
* Generate a teacher time report in platform by session only
* @package chamilo.admin
*/
use \Chamilo\CoreBundle\Entity\Session;
use \Doctrine\Common\Collections\Criteria;
$cidReset = true;
require_once '../inc/global.inc.php';
@ -12,6 +16,8 @@ require_once api_get_path(SYS_CODE_PATH) . 'work/work.lib.php';
api_protect_admin_script();
$toolName = get_lang('TeacherTimeReportBySession');
$em = Database::getManager();
$sessionsInfo = SessionManager::get_sessions_list([], ['name']);
$session = null;
@ -31,22 +37,27 @@ if (isset($_GET['session']) && intval($_GET['session'])) {
}
$data = [];
$coursesInfo = [];
$usersInfo = [];
if ($session) {
$sessionCourses = $session->getCourses();
foreach ($sessionCourses as $sessionCourse) {
$course = $sessionCourse->getCourse();
$userCourseSubscriptions = $session->getUserCourseSubscriptionsByStatus(
$course,
\Chamilo\CoreBundle\Entity\Session::COACH
$coursesInfo[$course->getId()] = $course->getCode();
$criteria = Criteria::create()->where(
Criteria::expr()->eq("status", Session::COACH)
);
$userCourseSubscriptions = $session
->getUserCourseSubscriptions()
->matching($criteria);
foreach ($userCourseSubscriptions as $userCourseSubscription) {
$user = $userCourseSubscription->getUser();
if (!array_key_exists($user->getId(), $data)) {
$data[$user->getId()] = [
if (!array_key_exists($user->getId(), $usersInfo)) {
$usersInfo[$user->getId()] = [
'code' => $user->getOfficialCode(),
'complete_name' => $user->getCompleteName(),
'time_in_platform' => api_time_to_hms(
@ -54,11 +65,15 @@ if ($session) {
),
'first_connection' => Tracking::get_first_connection_date($user->getId()),
'last_connection' => Tracking::get_last_connection_date($user->getId()),
'courses' => []
];
}
if (array_key_exists($course->getId(), $data[$user->getId()]['courses'])) {
$usersInfo[$user->getId()][$course->getId() . '_number_of_students'] = null;
$usersInfo[$user->getId()][$course->getId() . '_number_of_works'] = null;
$usersInfo[$user->getId()][$course->getId() . '_last_work'] = null;
$usersInfo[$user->getId()][$course->getId() . '_time_spent_of_course'] = null;
if (!$session->hasCoachInCourseWithStatus($user, $course)) {
continue;
}
@ -66,43 +81,52 @@ if ($session) {
->getRepository('ChamiloCourseBundle:CStudentPublication')
->findByTeacher($user, $course, $session->getId());
$lastWork = array_pop($works);
$lastFormattedDate = null;
if ($lastWork) {
$lastFormattedDate = api_format_date($lastWork->getSentDate()->getTimestamp(), DATE_TIME_FORMAT_SHORT);
$usersInfo[$user->getId()][$course->getId() . '_number_of_students'] = $sessionCourse->getNbrUsers();
$usersInfo[$user->getId()][$course->getId() . '_number_of_works'] = count($works);
$usersInfo[$user->getId()][$course->getId() . '_time_spent_of_course'] = api_time_to_hms(
Tracking::get_time_spent_on_the_course($user->getId(), $course->getId(), $session->getId())
);
if (!$lastWork) {
continue;
}
$data[$user->getId()]['courses'][$course->getId()] = [
'id' => $course->getId(),
'title' => $course->getTitle(),
'code' => $course->getCode(),
'number_of_students' => $sessionCourse->getNbrUsers(),
'number_of_works' => count($works),
'last_work' => $lastFormattedDate,
'time_spent_of_course' => api_time_to_hms(
Tracking::get_time_spent_on_the_course(
$user->getId(),
$course->getId(),
$session->getId()
)
)
];
$lastFormattedDate = api_format_date($lastWork->getSentDate()->getTimestamp(), DATE_TIME_FORMAT_SHORT);
$usersInfo[$user->getId()][$course->getId() . '_last_work'] = api_format_date(
$lastWork->getSentDate()->getTimestamp(),
DATE_TIME_FORMAT_SHORT
);
}
}
}
if (isset($_GET['export']) && $session && $data) {
$dataToExport = [];
if (isset($_GET['export']) && $session && ($coursesInfo && $usersInfo)) {
$fileName = get_lang('TeacherTimeReport') . ' ' . api_get_local_time();
$dataToExport = [];
$dataToExport[] = [$toolName, $session->getName()];
$dataToExport['headers'] = [
get_lang('OfficialCode'),
get_lang('CoachName'),
get_lang('TimeSpentOnThePlatform'),
get_lang('FirstLoginInPlatform'),
get_lang('LatestLoginInPlatform'),
];
foreach ($coursesInfo as $courseCode) {
$dataToExport['headers'][] = $courseCode;
$dataToExport['headers'][] = get_lang('NumberOfWorks');
$dataToExport['headers'][] = get_lang('LastWork');
$dataToExport['headers'][] = sprintf(get_lang('TimeReportForCourseX'), $courseCode);
}
foreach ($usersInfo as $user) {
$dataToExport[] = $user;
}
foreach ($data as $row) {
$headers = [
get_lang('OfficialCode'),
get_lang('Name'),
get_lang('TimeSpentOnThePlatform'),
get_lang('FirstLoginInPlatform'),
get_lang('LatestLoginInPlatform')
];
$contents = [
$row['code'],
$row['complete_name'],
@ -145,7 +169,6 @@ $interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH) . 'admin/teacher_time_report.php',
'name' => get_lang('TeacherTimeReport')
];
$toolName = get_lang('TeacherTimeReportBySession');
$actions = [];
@ -167,10 +190,11 @@ $view->assign('form', $form->returnForm());
if ($session) {
$view->assign('session', ['id' => $session->getId(), 'name' => $session->getName()]);
$view->assign('data', $data);
$view->assign('courses', $coursesInfo);
$view->assign('users', $usersInfo);
}
$template = $view->get_template('admin/teacher_time_report_by_session.tpl');
$template = $view->get_template('admin/teachers_time_by_session_report.tpl');
$content = $view->fetch($template);
$view->assign('header', $toolName);

@ -68,16 +68,16 @@ function confirmation(name) {
}
</script>';
$userGeolocalization = api_get_setting('enable_profile_user_address_geolocalization') == 'true';
$htmlHeadXtra[] = '<link href="'. api_get_path(WEB_PATH) .'web/assets/cropper/dist/cropper.min.css" rel="stylesheet">';
$htmlHeadXtra[] = '<script src="'. api_get_path(WEB_PATH) .'web/assets/cropper/dist/cropper.min.js"></script>';
$htmlHeadXtra[] = '<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=true" ></script>';
$htmlHeadXtra[] = '<script>
$(document).ready(function() {
var $image = $("#previewImage");
var $input = $("[name=\'cropResult\']");
var $cropButton = $("#cropButton");
var canvas = "";
var imageWidth = "";
var imageHeight = "";
$("input:file").change(function() {
var oFReader = new FileReader();
@ -146,6 +146,106 @@ $user_data['old_password'] = $user_data['password'];
$user_data['registration_date'] = api_get_local_time($user_data['registration_date']);
unset($user_data['password']);
if ($userGeolocalization) {
$htmlHeadXtra[] = '<script>
$(document).ready(function() {
var address = "' . $user_data['address'] . '";
initializeGeo(address, false);
$("#geolocalization").on("click", function() {
var address = $("#address").val();
initializeGeo(address, false);
return false;
});
$("#myLocation").on("click", function() {
myLocation();
return false;
});
$("#address").keypress(function (event) {
if (event.which == 13) {
$("#geolocalization").click();
return false;
}
});
});
function myLocation() {
if (navigator.geolocation) {
var geoPosition = function(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
var latLng = new google.maps.LatLng(lat, lng);
initializeGeo(false, latLng)
};
var geoError = function(error) {
alert("Geocode ' . get_lang('Error') . ': " + error);
};
var geoOptions = {
enableHighAccuracy: true
};
navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
}
}
function initializeGeo(address, latLng) {
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 15,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var parameter = address ? { "address": address } : latLng ? { "latLng": latLng } : false;
if (geocoder && parameter) {
geocoder.geocode(parameter, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
if (!address) {
$("#address").val(results[0].formatted_address);
}
var infowindow = new google.maps.InfoWindow({
content: "<b>" + $("#address").val() + "</b>",
size: new google.maps.Size(150, 50)
});
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: $("#address").val()
});
google.maps.event.addListener(marker, "click", function() {
infowindow.open(map, marker);
});
} else {
alert("' . get_lang("NotFound") . '");
}
} else {
alert("Geocode ' . get_lang('Error') . ': " + status);
}
});
}
}
</script>';
}
// Create the form
$form = new FormValidator(
'user_edit',
@ -205,6 +305,32 @@ if (api_get_setting('openid_authentication') == 'true') {
// Phone
$form->addElement('text', 'phone', get_lang('PhoneNumber'));
if ($userGeolocalization) {
// Geolocation
$form->addElement('text', 'address', get_lang('AddressField'), ['id' => 'address']);
$form->addHtml('
<div class="form-group">
<label for="geolocalization" class="col-sm-2 control-label"></label>
<div class="col-sm-8">
<button class="null btn btn-default " id="geolocalization" name="geolocalization" type="submit"><em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'</button>
<button class="null btn btn-default " id="myLocation" name="myLocation" type="submit"><em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'</button>
</div>
</div>
');
$form->addHtml('
<div class="form-group">
<label for="map" class="col-sm-2 control-label">
'.get_lang('Map').'
</label>
<div class="col-sm-8">
<div name="map" id="map" style="width:100%; height:300px;">
</div>
</div>
</div>
');
}
// Picture
$form->addElement('file', 'picture', get_lang('AddPicture'), array('id' => 'picture', 'class' => 'picture-form'));
$allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
@ -477,7 +603,8 @@ if ($form->validate()) {
$language,
null,
$send_mail,
$reset_password
$reset_password,
$user['address']
);
if (isset($user['student_boss'])) {

@ -6460,6 +6460,7 @@ function api_get_jquery_libraries_js($libraries) {
$js .= api_get_asset('blueimp-canvas-to-blob/js/canvas-to-blob.min.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.iframe-transport.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.fileupload.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-ui.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-process.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-image.js');
$js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-audio.js');

@ -859,7 +859,8 @@ class UserManager
$language = 'english',
$encrypt_method = '',
$send_email = false,
$reset_password = 0
$reset_password = 0,
$address
) {
$hook = HookUpdateUser::create();
if (!empty($hook)) {
@ -932,6 +933,7 @@ class UserManager
->setEmail($email)
->setOfficialCode($official_code)
->setPhone($phone)
->setAddress($address)
->setPictureUri($picture_uri)
->setExpirationDate($expiration_date)
->setActive($active)

@ -104,11 +104,10 @@ if ($session) {
}
if (isset($_GET['export']) && $session && ($coursesInfo && $usersInfo)) {
$dataToExport = [
[$toolName]
];
$fileName = 'works_in_session_' . api_get_local_time();
$dataToExport = [];
$dataToExport[] = [$toolName, $session->getName()];
$dataToExport['headers'][] = get_lang('OfficialCode');
$dataToExport['headers'][] = get_lang('StudentName');
$dataToExport['headers'][] = get_lang('TimeSpentOnThePlatform');
@ -166,7 +165,7 @@ if ($session) {
$view->assign('users', $usersInfo);
}
$template = $view->get_template('my_space/works.tpl');
$template = $view->get_template('my_space/works_in_session_report.tpl');
$content = $view->fetch($template);
$view->assign('header', $toolName);

@ -28,18 +28,16 @@
</script>
<div class="col-md-12">
<div class="actions">
<div class="row">
<div class="col-md-12">
<a href="{{ _p.web_self ~ '?' ~ {'export':'pdf','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
{{ 'pdf.png' | img(32, 'ExportToPDF'|get_lang ) }}
</a>
<a href="{{ _p.web_self ~ '?' ~ {'export':'xls','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
{{ 'export_excel.png' | img(32, 'ExportExcel'|get_lang ) }}
</a>
<a href="{{ _p.web_main }}admin/teacher_time_report_by_session.php">
{{ 'session.png'|img(32, 'Sessions'|get_lang) }}
</a>
</div>
<a href="{{ _p.web_main }}admin/teachers_time_by_session_report.php">
{{ 'session.png'|img(32, 'Sessions'|get_lang) }}
</a>
<div class="pull-right">
<a href="{{ _p.web_self ~ '?' ~ {'export':'pdf','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
{{ 'pdf.png' | img(32, 'ExportToPDF'|get_lang ) }}
</a>
<a href="{{ _p.web_self ~ '?' ~ {'export':'xls','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
{{ 'export_excel.png' | img(32, 'ExportExcel'|get_lang ) }}
</a>
</div>
</div>
<h1 class="page-header">{{ 'TeacherTimeReport' | get_lang }}</h1>

@ -2,6 +2,35 @@
{% if session %}
<h3 class="page-header">{{ session.name }}</h3>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>{{ 'OfficialCode'|get_lang }}</th>
<th>{{ 'CoachName'|get_lang }}</th>
<th>{{ 'TimeSpentOnThePlatform'|get_lang }}</th>
<th>{{ 'FirstLoginInPlatform'|get_lang }}</th>
<th>{{ 'LatestLoginInPlatform'|get_lang }}</th>
{% for course_code in courses %}
<th>{{ course_code }}</th>
<th>{{ 'NumberOfWorks'|get_lang }}</th>
<th>{{ 'LastWork'|get_lang }}</th>
<th>{{ 'TimeReportForCourseX'|get_lang|format(course.code) }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
{% for data in user %}
<td>{{ data }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% for row in data %}
<div class="table-responsive">

@ -2025,14 +2025,15 @@ function get_work_user_list(
$correction = '
<form
id="file_upload_'.$item_id.'"
class="work_correction_file_upload file_upload_small"
class="work_correction_file_upload file_upload_small fileinput-button"
action="'.api_get_path(WEB_AJAX_PATH).'work.ajax.php?'.api_get_cidreq().'&a=upload_correction_file&item_id='.$item_id.'" method="POST" enctype="multipart/form-data"
>
<div class="button-load">
<div class="text-center button-load">
'.get_lang('ClickOrDropOneFileHere').'
'.Display::return_icon('upload_file.png', get_lang('Correction'), [], ICON_SIZE_TINY).'
</div>
<input type="file" name="file" multiple>
<button type="submit"></button>
<input type="file" name="file" class="" multiple>
</form>
';
@ -2043,8 +2044,7 @@ function get_work_user_list(
downloadTable: $('.files'),
buildUploadRow: function (files, index) {
$('.files').show();
return
$('<tr><td>' + files[index].name + '<\/td>' +
return $('<tr><td>' + files[index].name + '<\/td>' +
'<td class=\"file_upload_progress\"><div><\/div><\/td>' +
'<td class=\"file_upload_cancel\">' +
'<button class=\"ui-state-default ui-corner-all\" title=\"".get_lang('Cancel')."\">' +

Loading…
Cancel
Save