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

1.10.x
Nicolas Ducoulombier 10 years ago
commit 69b5943743
  1. 3
      composer.json
  2. 24
      main/admin/skills_wheel.php
  3. 12
      main/admin/statistics/index.php
  4. 2
      main/auth/courses_controller.php
  5. 248
      main/course_description/course_description_controller.php
  6. 2
      main/course_info/infocours.php
  7. 4
      main/css/base.css
  8. 170
      main/gradebook/certificate_report.php
  9. 17
      main/gradebook/gradebook_display_certificate.php
  10. 37
      main/inc/ajax/model.ajax.php
  11. 4
      main/inc/ajax/skill.ajax.php
  12. 6
      main/inc/lib/api.lib.php
  13. 52
      main/inc/lib/course.lib.php
  14. 15
      main/inc/lib/course_category.lib.php
  15. 55
      main/inc/lib/group_portal_manager.lib.php
  16. 52
      main/inc/lib/sessionmanager.lib.php
  17. 6
      main/inc/lib/statistics.lib.php
  18. 3
      main/inc/lib/template.lib.php
  19. 9
      main/inc/lib/zombie/zombie_report.class.php
  20. 6
      main/lang/english/trad4all.inc.php
  21. 6
      main/lang/french/trad4all.inc.php
  22. 1
      main/lang/spanish/install.inc.php
  23. 22
      main/lang/spanish/trad4all.inc.php
  24. 9
      main/mySpace/company_reports.php
  25. 9
      main/mySpace/company_reports_resumed.php
  26. 9
      main/mySpace/student.php
  27. 13
      main/social/skills_wheel.php
  28. 137
      main/template/default/auth/sessions_catalog.tpl
  29. 65
      main/template/default/gradebook/certificate_report.tpl
  30. 3
      main/template/default/layout/head.tpl
  31. 116
      main/template/default/skill/skill_wheel.js.tpl
  32. 139
      main/template/default/skill/skill_wheel.tpl
  33. 92
      main/template/default/skill/skill_wheel_student.tpl
  34. 50
      main/work/work.lib.php
  35. 18
      plugin/resubscription/src/HookResubscription.php
  36. 4
      plugin/resubscription/src/Resubscription.php
  37. 71
      tests/scripts/userfields_to_groups.php

@ -65,7 +65,8 @@
"bower-asset/mediaelement": "2.16.*",
"bower-asset/modernizr": "2.8.*",
"bower-asset/jqueryui-timepicker-addon": "1.5.*",
"ramsey/array_column": "~1.1"
"ramsey/array_column": "~1.1",
"bower-asset/imageMap-resizer": "0.5.3"
},
"require-dev": {
"behat/behat": "2.5.*@stable",

@ -44,6 +44,30 @@ $url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?1=1';
$tpl->assign('url', $url);
$tpl->assign('isAdministration', true);
$dialogForm = new FormValidator('form', 'post', null, null, ['id' => 'add_item']);
$dialogForm->addHidden('id', null);
$dialogForm->addText('name', get_lang('Name'), true, ['id' => 'name']);
$dialogForm->addText('short_code', get_lang('ShortCode'), false, ['id' => 'short_code']);
$dialogForm->addSelect('parent_id', get_lang('Parent'), [], ['id' => 'parent_id']);
$dialogForm->addHtml('<ul id="skill_edit_holder" class="holder holder_simple"></ul>');
$dialogForm->addHtml('<div id="gradebook_row">');
$dialogForm->addSelect(
'gradebook_id',
[get_lang('Gradebook'), get_lang('WithCertificate')],
[],
['id' => 'gradebook_id']
);
$dialogForm->addHtml('<ul id="gradebook_holder" class="holder holder_simple"></ul>');
$dialogForm->addHtml('</div>');
$dialogForm->addTextarea('description', get_lang('Description'), ['id' => 'description', 'rows' => 7]);
$tpl->assign('dialogForm', $dialogForm->returnForm());
$saveProfileForm = new FormValidator('form', 'post', null, null, ['id' => 'dialog-form-profile']);
$saveProfileForm->addHidden('profile_id', null);
$saveProfileForm->addText('name', get_lang('Name'), true, ['id' => 'name_profile']);
$saveProfileForm->addTextarea('description', get_lang('Description'), ['id' => 'description_profile', 'rows' => 6]);
$tpl->assign('saveProfileForm', $saveProfileForm->returnForm());
$content = $tpl->fetch('default/skill/skill_wheel.tpl');
$tpl->assign('content', $content);
$tpl->display_no_layout_template();

@ -81,19 +81,19 @@ switch ($_REQUEST['report']) {
break;
case 'users':
// total amount of users
$teachers = $students = array();
$countInvisible = isset($_GET['count_invisible_courses']) ? intval($_GET['count_invisible_courses']) : null;
Statistics::printStats(
get_lang('NumberOfUsers'),
array(
get_lang('Teachers') => Statistics::countUsers(1, null, $_GET['count_invisible_courses']),
get_lang('Students') => Statistics::countUsers(5, null, $_GET['count_invisible_courses'])
get_lang('Teachers') => Statistics::countUsers(COURSEMANAGER, null, $countInvisible),
get_lang('Students') => Statistics::countUsers(STUDENT, null, $countInvisible)
)
);
$teachers = $students = array();
$countInvisible = isset($_GET['count_invisible_courses']) ? $_GET['count_invisible_courses'] : null;
foreach ($course_categories as $code => $name) {
$name = str_replace(get_lang('Department'), "", $name);
$teachers[$name] = Statistics::countUsers(1, $code, $countInvisible);
$students[$name] = Statistics::countUsers(5, $code, $countInvisible);
$teachers[$name] = Statistics::countUsers(COURSEMANAGER, $code, $countInvisible);
$students[$name] = Statistics::countUsers(STUDENT, $code, $countInvisible);
}
// docents for each course category
Statistics::printStats(get_lang('Teachers'), $teachers);

@ -532,7 +532,7 @@ class CoursesController
*/
public function getSessionIcon($sessionName)
{
return Display::return_icon('window_list.png', $sessionName, null, ICON_SIZE_BIG);
return Display::return_icon('window_list.png', $sessionName, null,ICON_SIZE_MEDIUM);
}
/**

@ -0,0 +1,248 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Class CourseDescriptionController
* This file contains class used like controller,
* it should be included inside a dispatcher file (e.g: index.php)
* @author Christian Fasanando <christian1827@gmail.com>
* @package chamilo.course_description
*/
class CourseDescriptionController
{
private $toolname;
private $view;
/**
* Constructor
*/
public function __construct()
{
$this->toolname = 'course_description';
$this->view = new View($this->toolname);
}
/**
* It's used for listing course description,
* render to listing view
* @param boolean true for listing history (optional)
* @param array message for showing by action['edit','add','destroy'] (optional)
*/
public function listing($history = false, $messages = array())
{
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
$data = array();
$course_description_data = $course_description->get_description_data();
$data['descriptions'] = $course_description_data['descriptions'];
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['messages'] = $messages;
$browser = api_get_navigator();
if (!is_array($data['descriptions'])) {
$data['descriptions'] = array($data['descriptions']);
}
foreach ($data['descriptions'] as $description) {
if (!empty($description['content'])
&& strpos($description['content'], '<iframe') !== false
&& $browser['name'] == 'Chrome'
) {
header("X-XSS-Protection: 0");
}
}
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('listing');
$this->view->render();
}
/**
* It's used for editing a course description,
* render to listing or edit view
* @param int description type
*/
public function edit($id, $description_type)
{
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
$data = array();
$data['id'] = $id;
if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {
if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
$check = Security::check_token();
if ($check) {
$title = $_POST['title'];
if (api_get_setting('wcag_anysurfer_public_pages') == 'true') {
$content = WCAG_Rendering::prepareXHTML();
} else {
$content = $_POST['contentDescription'];
}
$description_type = $_POST['description_type'];
$id = $_POST['id'];
$progress = $_POST['progress'];
$course_description->set_description_type($description_type);
$course_description->set_title($title);
$course_description->set_content($content);
$course_description->set_progress($progress);
$thematic_advance = $course_description->get_data_by_id($id);
if (!empty($thematic_advance)) {
$course_description->set_id($id);
$affected_rows = $course_description->update();
} else {
$affected_rows = $course_description->insert();
}
Security::clear_token();
}
if ($affected_rows) {
$message['edit'] = true;
}
$this->listing(false, $message);
} else {
$data['error'] = 1;
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_title'] = $_POST['title'];
$data['description_content'] = $_POST['contentDescription'];
$data['description_type'] = $_POST['description_type'];
$data['progress'] = $_POST['progress'];
$data['descriptions'] = $course_description->get_data_by_id($_POST['id']);
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
}
} else {
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_type'] = $description_type;
if (!empty($id)) {
if (isset($_GET['id_session'])) {
$session_id = intval($_GET['id_session']);
}
$course_description_data = $course_description->get_data_by_id(
$id,
null,
$session_id
);
$data['description_type'] = $course_description_data['description_type'];
$data['description_title'] = $course_description_data['description_title'];
$data['description_content'] = $course_description_data['description_content'];
$data['progress'] = $course_description_data['progress'];
$data['descriptions'] = $course_description->get_data_by_description_type(
$description_type,
null,
$session_id
);
}
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
}
}
/**
* It's used for adding a course description,
* render to listing or add view
*/
public function add()
{
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
$data = array();
if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {
if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
$check = Security::check_token();
if ($check) {
$title = $_POST['title'];
if (api_get_setting('wcag_anysurfer_public_pages') == 'true') {
$content = WCAG_Rendering::prepareXHTML();
} else {
$content = $_POST['contentDescription'];
}
$description_type = $_POST['description_type'];
if ($description_type >= ADD_BLOCK) {
$course_description->set_description_type($description_type);
$course_description->set_title($title);
$course_description->set_content($content);
$affected_rows = $course_description->insert(api_get_course_int_id());
}
Security::clear_token();
}
if ($affected_rows) {
$message['add'] = true;
}
$this->listing(false, $message);
} else {
$data['error'] = 1;
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_title'] = $_POST['title'];
$data['description_content'] = $_POST['contentDescription'];
$data['description_type'] = $_POST['description_type'];
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('add');
$this->view->render();
}
} else {
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_type'] = $course_description->get_max_description_type();
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('add');
$this->view->render();
}
}
/**
* It's used for destroy a course description,
* render to listing view
* @param int description type
*/
public function destroy($id)
{
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
if (!empty($id)) {
$course_description->set_id($id);
$affected_rows = $course_description->delete();
}
if ($affected_rows) {
$message['destroy'] = true;
}
$this->listing(false, $message);
}
}

@ -229,6 +229,8 @@ $group[]=$form->createElement('radio', 'email_alert_students_on_new_homework', n
$form->addGroup($group, '', array(get_lang("NewHomeworkEmailAlert")), '');
$group = array();
$group[]=$form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertActivateOnlyForTeachers'), 3);
$group[]=$form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertActivateOnlyForStudents'), 2);
$group[]=$form->createElement('radio', 'email_alert_manager_on_new_doc', get_lang('WorkEmailAlert'), get_lang('WorkEmailAlertActivate'), 1);
$group[]=$form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertDeactivate'), 0);
$form->addGroup($group, '', array(get_lang("WorkEmailAlert")), '');

@ -84,6 +84,10 @@ select {
#announcements-slider .carousel-indicators .active{
background: #C52D2F;
}
#announcements-slider .carousel-inner img {
height: auto;
width: 100%;
}
.carousel-indicators{
bottom: 0px !important;
}

@ -23,10 +23,23 @@ $interbreadcrumb[] = array(
$selectedSession = isset($_POST['session']) && !empty($_POST['session']) ? intval($_POST['session']) : 0;
$selectedCourse = isset($_POST['course']) && !empty($_POST['course']) ? intval($_POST['course']) : 0;
$selectedMonth = isset($_POST['month']) && !empty($_POST['month']) ? intval($_POST['month']) : 0;
$selectedYear = isset($_POST['year']) && !empty($_POST['year']) ? $_POST['year'] : null;
$selectedYear = isset($_POST['year']) && !empty($_POST['year']) ? trim($_POST['year']) : null;
$selectedStudent = isset($_POST['student']) && !empty($_POST['student']) ? intval($_POST['student']) : 0;
$userId = api_get_user_id();
$sessions = SessionManager::getSessionsCoachedByUser($userId);
$sessions = $courses = $months = $students = [0 => get_lang('Select')];
if (api_is_student_boss()) {
$userList = GroupPortalManager::getGroupUsersByUser($userId);
$sessionsList = SessionManager::getSessionsFollowedForGroupAdmin($userId);
} else {
$sessionsList = SessionManager::getSessionsCoachedByUser($userId);
}
foreach ($sessionsList as $session) {
$sessions[$session['id']] = $session['name'];
}
if ($selectedSession > 0) {
if (!SessionManager::isValidId($selectedSession)) {
@ -36,32 +49,39 @@ if ($selectedSession > 0) {
exit;
}
$courses = SessionManager::get_course_list_by_session_id($selectedSession);
$coursesList = SessionManager::get_course_list_by_session_id($selectedSession);
if (is_array($courses)) {
foreach ($courses as &$course) {
if (is_array($coursesList)) {
foreach ($coursesList as &$course) {
$course['real_id'] = $course['id'];
}
}
} else {
$courses = CourseManager::get_courses_list_by_user_id($userId);
if (api_is_student_boss()) {
$coursesList = CourseManager::getCoursesFollowedByGroupAdmin($userId);
} else {
$coursesList = CourseManager::get_courses_list_by_user_id($userId);
if (is_array($courses)) {
foreach ($courses as &$course) {
$courseInfo = api_get_course_info_by_id($course['real_id']);
if (is_array($coursesList)) {
foreach ($coursesList as &$course) {
$courseInfo = api_get_course_info_by_id($course['real_id']);
$course = array_merge($course, $courseInfo);
$course = array_merge($course, $courseInfo);
}
}
}
}
$months = array();
foreach ($coursesList as $course) {
if (isset($course['real_id'])) {
$courses[$course['real_id']] = $course['title'];
} else {
$courses[$course['id']] = $course['title'];
}
}
for ($key = 1; $key <= 12; $key++) {
$months[] = array(
'key' => $key,
'name' => sprintf("%02d", $key)
);
$months[$key] = sprintf("%02d", $key);
}
$exportAllLink = null;
@ -69,6 +89,7 @@ $certificateStudents = array();
$searchSessionAndCourse = $selectedSession > 0 && $selectedCourse > 0;
$searchCourseOnly = $selectedSession <= 0 && $selectedCourse > 0;
$searchStudentOnly = $selectedStudent > 0;
if ($searchSessionAndCourse || $searchCourseOnly) {
$selectedCourseInfo = api_get_course_info_by_id($selectedCourse);
@ -98,14 +119,23 @@ if ($searchSessionAndCourse || $searchCourseOnly) {
"cat_id" => $gradebook->get_id()
));
$sessionName = api_get_session_name($selectedSession);
$courseName = api_get_course_info($selectedCourseInfo['code'])['title'];
$studentList = GradebookUtils::get_list_users_certificates($gradebook->get_id());
$certificateStudents = array();
if (is_array($studentList) && !empty($studentList)) {
foreach ($studentList as $student) {
if (api_is_student_boss() && !in_array($student['user_id'], $userList)) {
continue;
}
$certificateStudent = array(
'fullName' => api_get_person_name($student['firstname'], $student['lastname']),
'sessionName' => $sessionName,
'courseName' => $courseName,
'certificates' => array()
);
@ -133,7 +163,7 @@ if ($searchSessionAndCourse || $searchCourseOnly) {
continue;
}
} elseif ($selectedMonth > 0 && !empty($selectedYear)) {
if ($creationMonthYear != sprintf("%d %s", $selectedMonth, $selectedYear)) {
if ($creationMonthYear != sprintf("%02d %s", $selectedMonth, $selectedYear)) {
continue;
}
}
@ -144,6 +174,62 @@ if ($searchSessionAndCourse || $searchCourseOnly) {
);
}
if (count($certificateStudent['certificates']) > 0) {
$certificateStudents[] = $certificateStudent;
}
}
}
}
} elseif ($searchStudentOnly) {
$selectedStudentInfo = api_get_user_info($selectedStudent);
if (empty($selectedStudentInfo)) {
Session::write('reportErrorMessage', get_lang('NoUser'));
Header::location($selfUrl);
}
$sessionList = SessionManager::getSessionsFollowedByUser($selectedStudent);
foreach ($sessionList as $session) {
$sessionCourseList = SessionManager::get_course_list_by_session_id($session['id']);
foreach ($sessionCourseList as $sessionCourse) {
$gradebookCategories = Category::load(null, null, $sessionCourse['code'], null, false, $session['id']);
$gradebook = null;
if (!empty($gradebookCategories)) {
$gradebook = current($gradebookCategories);
}
if (!is_null($gradebook)) {
$sessionName = $session['name'];
$courseName = $sessionCourse['title'];
$certificateStudent = [
'fullName' => $selectedStudentInfo['complete_name'],
'sessionName' => $sessionName,
'courseName' => $courseName,
'certificates' => []
];
$studentCertificates = GradebookUtils::get_list_gradebook_certificates_by_user_id(
$selectedStudent,
$gradebook->get_id()
);
if (!is_array($studentCertificates) || empty($studentCertificates)) {
continue;
}
foreach ($studentCertificates as $certificate) {
$certificateStudent['certificates'][] = array(
'createdAt' => api_convert_and_format_date($certificate['created_at']),
'id' => $certificate['id']
);
}
if (count($certificateStudent['certificates']) > 0) {
$certificateStudents[] = $certificateStudent;
}
@ -159,10 +245,54 @@ if (Session::has('reportErrorMessage')) {
$template->assign('errorMessage', Session::read('reportErrorMessage'));
}
$template->assign('selectedSession', $selectedSession);
$template->assign('selectedCourse', $selectedCourse);
$template->assign('selectedMonth', $selectedMonth);
$template->assign('selectedYear', $selectedYear);
$searchBySessionCourseDateForm = new FormValidator(
'certificate_report_form',
'post',
api_get_path(WEB_CODE_PATH) . 'gradebook/certificate_report.php'
);
$searchBySessionCourseDateForm->addSelect('session', get_lang('Sessions'), $sessions, ['id' => 'session']);
$searchBySessionCourseDateForm->addSelect('course', get_lang('Courses'), $courses, ['id' => 'course']);
$searchBySessionCourseDateForm->addGroup(
[
$searchBySessionCourseDateForm->createElement('select', 'month', null, $months, ['id' => 'month']),
$searchBySessionCourseDateForm->createElement(
'text',
'year',
null,
['id' => 'year', 'placeholder' => get_lang('Year')]
)
],
null,
get_lang('Date')
);
$searchBySessionCourseDateForm->addButtonSearch();
$searchBySessionCourseDateForm->setDefaults([
'session' => $selectedSession,
'course' => $selectedCourse,
'month' => $selectedMonth,
'year' => $selectedYear
]);
if (api_is_student_boss()) {
foreach ($userList as $studentId) {
$students[$studentId] = api_get_user_info($studentId)['complete_name_with_username'];
}
$searchByStudentForm = new FormValidator(
'certificate_report_form',
'post',
api_get_path(WEB_CODE_PATH) . 'gradebook/certificate_report.php'
);
$searchByStudentForm->addSelect('student', get_lang('Students'), $students, ['id' => 'student']);
$searchByStudentForm->addButtonSearch();
$searchByStudentForm->setDefaults([
'student' => $selectedStudent
]);
$template->assign('searchByStudentForm', $searchByStudentForm->returnForm());
}
$template->assign('searchBySessionCourseDateForm', $searchBySessionCourseDateForm->returnForm());
$template->assign('sessions', $sessions);
$template->assign('courses', $courses);
$template->assign('months', $months);

@ -8,7 +8,9 @@
require_once '../inc/global.inc.php';
$current_course_tool = TOOL_GRADEBOOK;
api_protect_course_script();
if (!api_is_student_boss()) {
api_protect_course_script();
}
set_time_limit(0);
ini_set('max_execution_time', 0);
@ -25,7 +27,7 @@ function confirmation() {
</script>";
api_block_anonymous_users();
if (!api_is_allowed_to_edit()) {
if (!api_is_allowed_to_edit() && !api_is_student_boss()) {
api_not_allowed(true);
}
@ -36,10 +38,15 @@ $filterOfficialCodeGet = isset($_GET['filter']) ? Security::remove_XSS($_GET['fi
switch ($action) {
case 'export_all_certificates':
$userList = array();
if (!empty($filterOfficialCodeGet)) {
$userList = UserManager::getUsersByOfficialCode($filterOfficialCodeGet);
if (api_is_student_boss()) {
$userList = GroupPortalManager::getGroupUsersByUser(api_get_user_id());
} else {
$userList = array();
if (!empty($filterOfficialCodeGet)) {
$userList = UserManager::getUsersByOfficialCode($filterOfficialCodeGet);
}
}
Category::exportAllCertificates($cat_id, $userList);
break;
case 'generate_all_certificates':

@ -211,39 +211,10 @@ switch ($action) {
}
if ($searchByGroups) {
$groups = GroupPortalManager::get_groups_by_user(api_get_user_id(), GROUP_USER_PERMISSION_ADMIN);
$groupsId = array_keys($groups);
$subgroupsId = [];
if (is_array($groupsId)) {
foreach ($groupsId as $groupId) {
$subgroupsId = array_merge(
$subgroupsId,
GroupPortalManager::getGroupsByDepthLevel($groupId)
);
}
$groupsId = array_merge(
$groupsId,
$subgroupsId
);
foreach ($groupsId as $groupId) {
$groupUsers = GroupPortalManager::get_users_by_group($groupId);
if (!is_array($groupUsers)) {
continue;
}
foreach ($groupUsers as $memberId => $member) {
if ($member['user_id'] == $userId ) {
continue;
}
$userIdList[] = intval($member['user_id']);
}
}
}
$userIdList = array_merge(
$userIdList,
GroupPortalManager::getGroupUsersByUser(api_get_user_id())
);
}
if (is_array($userIdList)) {

@ -212,12 +212,13 @@ switch ($action) {
break;
case 'profile_matches':
$skill_rel_user = new SkillRelUser();
$skills = $_REQUEST['skill_id'];
$skills = (!empty($_REQUEST['skill_id'])?$_REQUEST['skill_id']:array());
$total_skills_to_search = $skills;
$users = $skill_rel_user->get_user_by_skills($skills);
$user_list = array();
$count_skills = count($skills);
$ordered_user_list = null;
if (!empty($users)) {
foreach ($users as $user) {
@ -255,7 +256,6 @@ switch ($action) {
$user_list[$user['user_id']]['total_found_skills'] = $found_counts;
}
$ordered_user_list = array();
foreach ($user_list as $user_id => $user_data) {
$ordered_user_list[$user_data['total_found_skills']][] = $user_data;
}

@ -71,6 +71,12 @@ define('COURSE_REQUEST_ACCEPTED', 1);
define('COURSE_REQUEST_REJECTED', 2);
define('DELETE_ACTION_ENABLED', false);
// EMAIL SENDING RECIPIENT CONSTANTS
define('SEND_EMAIL_EVERYONE', 1);
define('SEND_EMAIL_STUDENTS', 2);
define('SEND_EMAIL_TEACHERS', 3);
// SESSION VISIBILITY CONSTANTS
define('SESSION_VISIBLE_READ_ONLY', 1);
define('SESSION_VISIBLE', 2);

@ -5682,4 +5682,56 @@ class CourseManager
}
return $courses;
}
/**
* Get list of courses based on users of a group for a group admin
* @param int $userId The user id
* @return array
*/
public static function getCoursesFollowedByGroupAdmin($userId)
{
$coursesList = [];
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
$courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$userIdList = GroupPortalManager::getGroupUsersByUser($userId);
if (empty($userIdList)) {
return [];
}
$sql = "SELECT DISTINCT(c.id), c.title "
. "FROM $courseTable c "
. "INNER JOIN $courseUserTable cru ON c.code = cru.course_code "
. "WHERE ( "
. "cru.user_id IN(" . implode(', ', $userIdList) . ") "
. "AND cru.relation_type = 0 "
. ")";
if (api_is_multiple_url_enabled()) {
$courseAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$accessUrlId = api_get_current_access_url_id();
if ($accessUrlId != -1) {
$sql = "SELECT DISTINCT(c.id), c.title "
. "FROM $courseTable c "
. "INNER JOIN $courseUserTable cru ON c.code = cru.course_code "
. "INNER JOIN $courseAccessUrlTable crau ON c.code = crau.course_code "
. "WHERE crau.access_url_id = $accessUrlId "
. "AND ( "
. "cru.id_user IN (" . implode(', ', $userIdList) . ") "
. "AND cru.relation_type = 0 "
. ")";
}
}
$result = Database::query($sql);
while ($row = Database::fetch_assoc($result)) {
$coursesList[] = $row;
}
return $coursesList;
}
}

@ -932,6 +932,7 @@ function getCataloguePagination($pageCurrent, $pageLength, $pageTotal)
{
// Start empty html
$pageDiv = '';
$html='';
$pageBottom = max(1, $pageCurrent - 3);
$pageTop = min($pageTotal, $pageCurrent + 3);
@ -970,17 +971,11 @@ function getCataloguePagination($pageCurrent, $pageLength, $pageTotal)
}
// Complete pagination html
$pageDiv = Display::div(
Display::tag(
'ul',
$pageDiv
),
array(
'class' => 'pagination pagination-centered',
)
);
$pageDiv = Display::tag('ul',$pageDiv,array('class' => 'pagination'));
return $pageDiv;
$html.='<nav>'.$pageDiv.'</nav>';
return $html;
}
/**

@ -1359,4 +1359,59 @@ class GroupPortalManager
}
return true;
}
/**
* Get the group member list by a user and his group role
* @param int $userId The user ID
* @param int $relationType Optional. The relation type. GROUP_USER_PERMISSION_ADMIN by default
* @param boolean $includeSubgroupsUsers Optional. Whether include the users from subgroups
* @return array
*/
public static function getGroupUsersByUser(
$userId,
$relationType = GROUP_USER_PERMISSION_ADMIN,
$includeSubgroupsUsers = true
)
{
$userId = intval($userId);
$groups = GroupPortalManager::get_groups_by_user($userId, $relationType);
$groupsId = array_keys($groups);
$subgroupsId = [];
$userIdList = [];
if ($includeSubgroupsUsers) {
foreach ($groupsId as $groupId) {
$subgroupsId = array_merge($subgroupsId, GroupPortalManager::getGroupsByDepthLevel($groupId));
}
$groupsId = array_merge($groupsId, $subgroupsId);
}
$groupsId = array_unique($groupsId);
if (empty($groupsId)) {
return [];
}
foreach ($groupsId as $groupId) {
$groupUsers = GroupPortalManager::get_users_by_group($groupId);
if (empty($groupUsers)) {
continue;
}
foreach ($groupUsers as $member) {
if ($member['user_id'] == $userId) {
continue;
}
$userIdList[] = intval($member['user_id']);
}
}
return array_unique($userIdList);
}
}

@ -5952,4 +5952,56 @@ class SessionManager
return false;
}
/**
* Get list of sessions based on users of a group for a group admin
* @param int $userId The user id
* @return array
*/
public static function getSessionsFollowedForGroupAdmin($userId)
{
$sessionList = array();
$sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
$sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
$userIdList = GroupPortalManager::getGroupUsersByUser($userId);
if (empty($userIdList)) {
return [];
}
$sql = "SELECT DISTINCT s.* "
. "FROM $sessionTable s "
. "INNER JOIN $sessionUserTable sru ON s.id = sru.id_session "
. "WHERE ( "
. "sru.id_user IN (" . implode(', ', $userIdList) . ") "
. "AND sru.relation_type = 0"
. ")";
if (api_is_multiple_url_enabled()) {
$sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
$accessUrlId = api_get_current_access_url_id();
if ($accessUrlId != -1) {
$sql = "SELECT DISTINCT s.* "
. "FROM $sessionTable s "
. "INNER JOIN $sessionUserTable sru ON s.id = sru.id_session "
. "INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id "
. "WHERE srau.access_url_id = $accessUrlId "
. "AND ( "
. "sru.id_user IN (" . implode(', ', $userIdList) . ") "
. "AND sru.relation_type = 0"
. ")";
}
}
$result = Database::query($sql);
while ($row = Database::fetch_assoc($result)) {
$sessionList[] = $row;
}
return $sessionList;
}
}

@ -247,7 +247,7 @@ class Statistics
$row[2] = $row[2];
} else {
if (!empty($row[2])) {
$originalData = $row[2];
$originalData = str_replace('\\', '', $row[2]);
$row[2] = unserialize($originalData);
if (is_array($row[2]) && !empty($row[2])) {
$row[2] = implode_with_key(', ', $row[2]);
@ -596,8 +596,8 @@ class Statistics
$table = new SortableTable(
'activities',
array('Statistics', 'get_number_of_activities'),
array('Statistics','get_activities_data'),
array('Statistics', 'getNumberOfActivities'),
array('Statistics','getActivitiesData'),
5,
50,
'DESC'

@ -615,7 +615,8 @@ class Template
'bootstrap-daterangepicker/daterangepicker.js',
'jquery-timeago/jquery.timeago.js',
'mediaelement/build/mediaelement-and-player.min.js',
'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.js'
'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.js',
'imagemap-resizer/js/imageMapResizer.min.js'
];
if ($isoCode != 'en') {

@ -40,8 +40,8 @@ class ZombieReport implements Countable
array(
'name' => 'ceiling',
'label' => get_lang('LastAccess'),
'type' => 'datepickerdate',
'default' => $this->get_ceiling(),
'type' => 'date_picker',
'default' => $this->get_ceiling('Y-m-d'),
'rules' => array(
// array(
// 'type' => 'required',
@ -121,7 +121,7 @@ class ZombieReport implements Countable
return $form->isSubmitted() == false || $form->validate();
}
function get_ceiling()
function get_ceiling($format = null)
{
$result = Request::get('ceiling');
$result = $result ? $result : ZombieManager::last_year();
@ -130,6 +130,9 @@ class ZombieReport implements Countable
$result = is_array($result) ? mktime(0, 0, 0, $result['F'], $result['d'], $result['Y']) : $result;
$result = is_numeric($result) ? (int) $result : $result;
$result = is_string($result) ? strtotime($result) : $result;
if ($format) {
$result = date($format, $result);
}
return $result;
}

@ -557,7 +557,7 @@ $Remote = "Remote";
$FileToUpload = "SCORM or AICC file to upload";
$ContentMaker = "Authoring tool";
$ContentProximity = "Course location";
$UploadLocalFileFromGarbageDir = "Upload local file from main/archive directory";
$UploadLocalFileFromGarbageDir = "Upload local .zip package from the archive/ directory";
$ThisItemIsNotExportable = "This learning object or activity is not SCORM compliant. That's why it is not exportable.";
$MoveCurrentChapter = "Move the current section";
$GenericScorm = "Generic Scorm";
@ -7067,4 +7067,8 @@ $DataTableSearch = "Search";
$HideColumn = "Hide column";
$DisplayColumn = "Show column";
$LegalAgreementAccepted = "Legal agreement accepted";
$WorkEmailAlertActivateOnlyForTeachers = "Activate only for teachers e-mail alert on new work submission";
$WorkEmailAlertActivateOnlyForStudents = "Activate only for students e-mail alert on new work submission";
$Uncategorized = "Uncategorized";
$NaturalYear = "Natural year";
?>

@ -550,7 +550,7 @@ $Remote = "Distant";
$FileToUpload = "Fichier à envoyer";
$ContentMaker = "Créateur du contenu";
$ContentProximity = "Situation du parcours";
$UploadLocalFileFromGarbageDir = "Intégrer un fichier déposé par FTP sur le serveur";
$UploadLocalFileFromGarbageDir = "Intégrer un paquet zip déposé par FTP sur le serveur dans le répertoire archive/";
$ThisItemIsNotExportable = "Cet item n'est pas compatible SCORM pour le moment. Il n'est donc pas exportable.";
$MoveCurrentChapter = "Déplacer le chapitre courant";
$GenericScorm = "Scorm générique";
@ -7056,4 +7056,8 @@ $DataTableSearch = "Recherche";
$HideColumn = "Cacher la colonne";
$DisplayColumn = "Montrer la colonne";
$LegalAgreementAccepted = "Conditions légales acceptées";
$WorkEmailAlertActivateOnlyForTeachers = "Envoyer un e-mail aux formateurs uniquement à la réception d'un nouveau travail";
$WorkEmailAlertActivateOnlyForStudents = "Envoyer un e-mail à l'étudiant uniquement pour confirmer la réception d'un nouveau travail";
$Uncategorized = "Non catégorisé";
$NaturalYear = "Année naturelle (365 jours)";
?>

@ -46,6 +46,7 @@ $Recommended = "Recomendado";
$ScormDB = "Base de datos SCORM";
$AdminLastName = "Apellidos del administrador";
$AdminPhone = "Teléfono del administrador";
$UpgradeFromLMS19x = "Actualizar desde una versión 1.9.*";
$AdminFirstName = "Nombre del administrador";
$InstituteURL = "URL de la organización";
$UserDB = "Base de datos de usuarios";

@ -561,7 +561,7 @@ $Remote = "Remoto";
$FileToUpload = "Archivo a enviar";
$ContentMaker = "Creador de contenidos";
$ContentProximity = "Localización del contenido";
$UploadLocalFileFromGarbageDir = "Enviar archivo local desde el directorio main/archive";
$UploadLocalFileFromGarbageDir = "Enviar paquete .zip local desde el directorio archive/";
$ThisItemIsNotExportable = "Este objeto de aprendizaje no es compatible con SCORM. Por esta razón no es exportable.";
$MoveCurrentChapter = "Mover el capítulo actual";
$GenericScorm = "SCORM genérico";
@ -642,7 +642,7 @@ $BUCourseDataOfMainBase = "Copia de seguridad de los datos del curso en la base
$BUUsersInMainBase = "Copia de seguridad de los datos de los usuarios en la base de datos principal";
$BUAnnounceInMainBase = "Copia de seguridad de los datos de los anuncios en la base de datos principal";
$BackupOfDataBase = "Copia de seguridad de la base de datos";
$ExpirationDate = "Finalizado";
$ExpirationDate = "Fecha de expiración";
$LastEdit = "Última edición";
$LastVisit = "Última visita";
$Subscription = "Inscripción";
@ -1302,6 +1302,7 @@ $DeleteSelectedClasses = "Eliminar las clases seleccionadas";
$DeleteSelectedGroups = "Eliminar los grupos seleccionados";
$Administrator = "Administrador";
$ChangePicture = "Cambiar la imagen";
$myCoursesSessionView = "Viesta por sesión";
$AddUsers = "Añadir usuarios";
$AddGroups = "Crear grupos en la red social";
$AddClasses = "Crear clases";
@ -1365,6 +1366,7 @@ $NoCategories = "Sin categorías";
$AllowCoursesInCategory = "Permitir añadir cursos a esta categoría";
$GoToForum = "Ir al foro";
$CategoryCode = "Código de la categoría";
$MetaTwitterCreatorComment = "Cuenta personal de Twitter (ej: @ywarnier) que representa la *persona* que está a cargo de o representa este portal. Este campo es opcional.";
$EditNode = "Editar esta categoría";
$OpenNode = "Abrir esta categoría";
$DeleteNode = "Eliminar esta categoría";
@ -1375,6 +1377,7 @@ $TreeRecountedIn = "Árbol recontado en";
$RebuildTree = "Reconstruir el árbol";
$RefreshNbChildren = "Actualizar el número de hijos";
$ShowTree = "Ver el árbol";
$MetaImagePathTitle = "Ruta de imagen Meta";
$LogDeleteCat = "Categoría eliminada";
$RecountChildren = "Recontar los hijos";
$UpInSameLevel = "Subir en este nivel";
@ -1431,6 +1434,7 @@ $CourseCreationSucceeded = "El curso ha sido creado.";
$OnTheHardDisk = "en el disco duro";
$IsVirtualCourse = "Curso virtual";
$AnnouncementUpdated = "El anuncio ha sido actualizado";
$MetaImagePathComment = "Esta es la ruta hacia una imagen, dentro de la estructura de carpetas de Chamilo (ej: home/image.png) que representará su portal en una Twitter Card o una OpenGraph Card cuando alguien publique un enlace a su portal en un sitio que soporte uno de estos dos formatos. Twitter recomienda que la imagen sea de 120 x 120 píxeles de dimensiones, pero a veces se reduce a 120x90, por lo que debería quedar bien en ambas dimensiones.";
$PermissionsForNewFiles = "Permisos para los nuevos archivos";
$PermissionsForNewFilesComment = "La posibilidad de definir la configuración de los permisos asignados a los nuevos archivos, aumenta la seguridad contra los ataques de hackers que puedan enviar material peligroso a la plataforma. La configuración por defecto (0550) debe ser suficiente para dar a su servidor un nivel de protección razonable. El formato proporcionado utiliza la terminología de UNIX Propietario-Grupo-Otros, con los permisos de Lectura-Escritura-Ejecución.";
$Guest = "Invitado";
@ -1508,6 +1512,7 @@ $EditNews = "Editar noticias";
$EditCategories = "Editar categorías";
$EditHomePage = "Editar la página principal";
$AllowUserHeadingsComment = "¿ El administrador de un curso puede definir cabeceras para obtener información adicional de los usuarios ?";
$MetaTwitterSiteTitle = "Cuenta Twitter Site";
$Languages = "Idiomas";
$NoticeTitle = "Título de la noticia";
$NoticeText = "Texto de la noticia";
@ -1530,6 +1535,7 @@ $AllowPersonalAgendaTitle = "Agenda personal";
$AllowPersonalAgendaComment = "¿ El usuario puede añadir elementos de la agenda personal a la sección 'Mi agenda' ?";
$CurrentValue = "Valor actual";
$AlreadyRegisteredToSession = "Ya está registrado en la sesión";
$myCoursesDefaultView = "Vista por defecto";
$UserPassword = "Contraseña";
$SubscriptionAllowed = "Inscripción";
$UnsubscriptionAllowed = "Anular inscripción";
@ -1600,6 +1606,7 @@ $ShowOnlineUsers = "Mostrar el número de usuarios en línea en todas las págin
$ShowOnlineCourse = "Mostrar el número de usuarios en línea en este curso";
$ShowIconsInNavigationsMenuTitle = "¿Mostrar los iconos en el menú de navegación?";
$SeeAllRightsAllRolesForSpecificLocation = "Ver todos los perfiles y permisos para un lugar específico";
$MetaTwitterCreatorTitle = "Cuenta Twitter Creator";
$ClassesSubscribed = "Las clases seleccionadas fueron inscritas en los cursos seleccionados";
$RoleId = "ID del perfil";
$RoleName = "Nombre del perfil";
@ -1677,6 +1684,7 @@ $EnableToolIntroductionTitle = "Activar introducción a las herramientas";
$EnableToolIntroductionComment = "Habilitar una introducción en cada herramienta de la página principal";
$BreadCrumbsCourseHomepageTitle = "Barra de navegación de la página principal del curso";
$BreadCrumbsCourseHomepageComment = "La barra de navegación es un sistema de navegación horizontal mediante enlaces que generalmente se sitúa en la zona superior izquierda de su página. Esta opción le permite seleccionar el contenido de esta barra en la página principal de cada curso";
$MetaTwitterSiteComment = "La cuenta Twitter Site es una cuenta Twitter (ej: @chamilo_news) que se relaciona con su portal. Usualmente, se trata de una cuenta temporal o institucional, más no de una cuenta de un indivíduo en particular (como la es la del Twitter Creator). Este campo es obligatorio para mostrar el resto de campos de las Twitter Cards.";
$LoginPageMainArea = "Area principal de la página de acceso";
$LoginPageMenu = "Menú de la página de acceso";
$CampusHomepageMainArea = "Area principal de la página de acceso a la plataforma";
@ -1955,6 +1963,10 @@ $IsNotWritable = "no se puede escribir";
$FieldMovedDown = "El campo ha sido desplazado hacia abajo";
$CannotMoveField = "No se puede mover el campo";
$FieldMovedUp = "El campo ha sido desplazado hacia arriba";
$MetaTitleTitle = "Título meta OpenGraph";
$MetaDescriptionComment = "Esto incluirá el tag de descripción OpenGraph (og:description) en las cabeceras (invisibles) de su portal.";
$MetaDescriptionTitle = "Descripción Meta";
$MetaTitleComment = "Esto incluirá el tag OpenGraph Title (og:title) en las cabeceras (invisibles) de su portal.";
$FieldDeleted = "El campo ha sido eliminado";
$CannotDeleteField = "No se puede eliminar el campo";
$AddUsersByCoachTitle = "Registro de usuarios por el tutor";
@ -5873,6 +5885,7 @@ $webserver = "Webserver";
$mysql = "mysql";
$NotInserted = "No insertado";
$Multipleresponse = "Respuesta múltiple";
$EnableMathJaxComment = "Activar el editor matemático MathJax.";
$YouCanNowLoginAtXUsingTheLoginAndThePasswordYouHaveProvided = "Ahora puede identificarse en %s usando el nombre de usuario y contraseña que le han sido facilitados";
$HaveFun = "Diviértase,";
$AreYouSureToEditTheUserStatus = "¿Está seguro de querer editar el estatus de usuario?";
@ -6124,6 +6137,7 @@ $MultipleAnswerCombinationTrueFalse = "Combinación v/f/no-se";
$DontKnow = "No se";
$ExamNotAvailableAtThisTime = "Examen no disponible en este momento";
$LoginOrEmailAddress = "Nombre de usuario o dirección e-mail";
$EnableMathJaxTitle = "Activar MathJax";
$Activate = "Activar";
$Deactivate = "Desactivar";
$ConfigLearnpath = "Configurar la herramienta lecciones";
@ -7082,4 +7096,8 @@ $DataTableSearch = "Buscar";
$HideColumn = "Ocultar columna";
$DisplayColumn = "Mostrar columna";
$LegalAgreementAccepted = "Condiciones legales aceptadas";
$WorkEmailAlertActivateOnlyForTeachers = "Activar sólo para profesores el aviso por correo electrónico del envío de una nueva tarea";
$WorkEmailAlertActivateOnlyForStudents = "Activar sólo para alumnos el aviso por correo electrónico del envío de una nueva tarea";
$Uncategorized = "Sin categoría";
$NaturalYear = "Año natural";
?>

@ -110,6 +110,15 @@ if (api_is_student_boss()) {
Display::return_icon("statistics.png", get_lang("CompanyReport"), array(), ICON_SIZE_MEDIUM),
"#"
);
$actions .= Display::url(
Display::return_icon(
"certificate_list.png",
get_lang("GradebookSeeListOfStudentsCertificates"),
[],
ICON_SIZE_MEDIUM
),
api_get_path(WEB_CODE_PATH) . "gradebook/certificate_report.php"
);
}
$content = '<div class="actions">';

@ -99,6 +99,15 @@ if (api_is_student_boss()) {
Display::return_icon("statistics.png", get_lang("CompanyReport"), array(), ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH) . "mySpace/company_reports.php"
);
$actions .= Display::url(
Display::return_icon(
"certificate_list.png",
get_lang("GradebookSeeListOfStudentsCertificates"),
[],
ICON_SIZE_MEDIUM
),
api_get_path(WEB_CODE_PATH) . "gradebook/certificate_report.php"
);
}
$content = '<div class="actions">';

@ -211,6 +211,15 @@ if (api_is_drh()) {
Display::return_icon("statistics.png", get_lang("CompanyReport"), array(), ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH) . "mySpace/company_reports.php"
);
$actions .= Display::url(
Display::return_icon(
"certificate_list.png",
get_lang("GradebookSeeListOfStudentsCertificates"),
[],
ICON_SIZE_MEDIUM
),
api_get_path(WEB_CODE_PATH) . "gradebook/certificate_report.php"
);
}
$actions .= '<span style="float:right">';

@ -54,6 +54,19 @@ $tpl->assign('ranking', $ranking);
$tpl->assign('countSkill', $countSkill);
$tpl->assign('mySkills', $mySkills);
$dialogForm = new FormValidator('form', 'post', null, null, ['id' => 'add_item']);
$dialogForm->addHidden('id', null);
$dialogForm->addText('name', get_lang('Name'), false, ['id' => 'name']);
$dialogForm->addText('short_code', get_lang('ShortCode'), false, ['id' => 'short_code']);
$dialogForm->addLabel(get_lang('ShortCode'), '<ul id="skill_edit_holder" class="holder holder_simple"></ul>');
$dialogForm->addHtml('<div id="gradebook_row">');
$dialogForm->addLabel([get_lang('Gradebook'), get_lang('WithCertificate')], '<ul id="gradebook_holder" class="holder holder_simple"></ul>');
$dialogForm->addHtml('<ul id="gradebook_holder" class="holder holder_simple"></ul>');
$dialogForm->addHtml('</div>');
$dialogForm->addTextarea('description', get_lang('Description'), ['id' => 'description', 'rows' => 7]);
$tpl->assign('dialogForm', $dialogForm->returnForm());
$content = $tpl->fetch('default/skill/skill_wheel_student.tpl');
$tpl->assign('content', $content);
$tpl->display_no_layout_template();

@ -7,13 +7,13 @@
dateFormat: 'yy-mm-dd'
});
$('.accordion').click(function(e) {
$('#list-course').click(function(e) {
e.preventDefault();
var tempTarget = e.target.toString().split('#');
tempTarget = '#' + tempTarget[1];
// use the target of the link as the ID of the element to find
var target = $(tempTarget);
var targetContent = target.find('.accordion-inner');
var targetContent = target.find('.list');
if (targetContent.is(':empty')) {
var idParts = tempTarget.split('-');
@ -42,11 +42,11 @@
targetContent.html('<ul class="items-session">' + coursesUL + '</ul>');
target.css({
height: targetContent.outerHeight()
}).addClass('in');
}).addClass(' in');
}
});
} else {
target.addClass('in');
target.addClass(' in');
}
});
});
@ -54,105 +54,102 @@
<div class="col-md-3">
{% if showCourses %}
<div class="well">
{% if not hiddenLinks %}
<div class="panel panel-default">
<div class="panel-body">
{% if not hiddenLinks %}
<form class="form-search" method="post" action="{{ courseUrl }}">
<fieldset>
<input type="hidden" name="sec_token" value="{{ searchToken }}">
<input type="hidden" name="search_course" value="1" />
<div class="control-group">
<div class="controls">
<div class="input-append">
<input class="span2" type="text" name="search_term" />
<button class="btn btn-default" type="submit"><i class="fa fa-search"></i> {{ 'Search' | get_lang }}</button>
</div>
</div>
<div class="form-group">
<input type="text" name="search_term" class="form-control"/>
<button class="btn btn-block btn-default" type="submit"><i class="fa fa-search"></i> {{ 'Search' | get_lang }}</button>
</div>
</fieldset>
</form>
{% endif %}
{% endif %}
{% if coursesCategoriesList is not empty %}
<a class="btn btn-default" href="{{ api_get_self }}?action=display_random_courses">{{ 'RandomPick' | get_lang }}</a>
{% endif %}
{% if coursesCategoriesList is not empty %}
<a class="btn btn-block btn-default" href="{{ api_get_self }}?action=display_random_courses">{{ 'RandomPick' | get_lang }}</a>
{% endif %}
</div>
</div>
{% if coursesCategoriesList is not empty %}
<div class="well sidebar-nav">
<h4>{{ 'CourseCategories' | get_lang }}</h4>
<ul class="nav nav-list">
{{ coursesCategoriesList }}
</ul>
<div class="sidebar-nav">
<div class="panel panel-default">
<div class="panel-heading">
{{ 'CourseCategories' | get_lang }}
</div>
<div class="panel-body">
<ul class="list-categories">
{{ coursesCategoriesList }}
</ul>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% if showSessions %}
<div class="well sidebar-nav">
<h4>{{ 'Sessions' | get_lang }}</h4>
<ul class="nav nav-list">
<li>{{ 'SearchSessions' | get_lang }}</li>
<li>
<div class="sidebar-nav">
<div class="panel panel-default">
<div class="panel-heading">
{{ 'Sessions' | get_lang }}
</div>
<div class="panel-body">
<form class="form-search" method="post" action="{{ api_get_self }}?action=display_sessions">
<div class="input-append">
<input type="date" name="date" id="date" class="span2 search-session" value="{{ searchDate }}" readonly>
<button class="btn btn-default" type="submit"><i class="fa fa-search"></i> {{ 'Search' | get_lang }}</button>
<div class="form-group">
<input type="date" name="date" id="date" class="form-control" value="{{ searchDate }}" readonly>
<button class="btn btn-block btn-default" type="submit"><i class="fa fa-search"></i> {{ 'Search' | get_lang }}</button>
</div>
</form>
</li>
</ul>
</div>
</div>
</div>
{% endif %}
</div>
<div class="col-md-9">
{% for session in sessions_blocks %}
<div class="well well-small session-group" id="session-{{ session.id }}">
<div class="row">
<div class="col-md-9">
<div class="row padding-clear">
<div class="col-md-2">
<span class="thumbnail">
{{ session.icon }}
</span>
</div>
<div class="col-md-10 border-info">
<h3>{{ session.name }}</h3>
<div class="tutor">
<img src="{{ 'teacher.png' | icon(22) }}" width="16"> {{ 'GeneralCoach' | get_lang }} {{ session.coach_name }}
</div>
<div class="panel panel-default" id="panel-{{ session.id }}">
<div class="panel-heading">
{{ session.icon }} {{ session.name }}
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-9">
<div class="tutor">
<img src="{{ 'teacher.png' | icon(22) }}" width="16"> {{ 'GeneralCoach' | get_lang }} {{ session.coach_name }}
</div>
</div>
<div class="row">
<div class="accordion" id="session-{{ session.id }}-accordion">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#session-{{ session.id }}-accordion" href="#session-{{ session.id }}-courses">
{{ 'CourseList' | get_lang }}
</a>
</div>
<div id="session-{{ session.id }}-courses" class="accordion-body collapse in">
<div class="accordion-inner"></div>
</div>
</div>
<a id="list-course" class="btn btn-default" data-toggle="collapse" href="#session-{{ session.id }}-courses">
{{ 'CourseList' | get_lang }}
</a>
<div class="collapse" id="session-{{ session.id }}-courses">
<div class="list"></div>
</div>
</div>
</div>
<div class="col-md-3">
{% if session.showDescription %}
<div class="col-md-3">
{% if session.showDescription %}
<div class="buttom-subscribed">
<a class="ajax btn btn-large btn-info" href="{{ _p.web_ajax }}session.ajax.php?a=get_description&session={{ session.id }}">{{ 'Description' | get_lang }}</a>
</div>
{% endif %}
{% endif %}
<div class="buttom-subscribed">
{% if session.is_subscribed %}
<div class="buttom-subscribed">
{% if session.is_subscribed %}
{{ already_subscribed_label }}
{% else %}
{% else %}
{{ session.subscribe_button }}
{% endif %}
{% endif %}
</div>
<div class="time"><img src="{{ 'agenda.png' | icon(22) }}"> {{ session.date }}</div>
</div>
<div class="time"><img src="{{ 'agenda.png' | icon(22) }}"> {{ session.date }}</div>
</div>
</div>
</div>
{% endfor %}

@ -10,8 +10,6 @@
a: 'display_sessions_courses',
session: sessionId
}, function (courseList) {
var $option = null;
$('<option>', {
value: 0,
text: "{{ 'Select' | get_lang }}"
@ -30,63 +28,32 @@
});
</script>
<form action="{{ _p.web_main }}gradebook/certificate_report.php" method="post" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="session">{{ 'Sessions' | get_lang }}</label>
<div class="controls">
<select name="session" id="session">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for session in sessions %}
<option value="{{ session.id }}" {{ selectedSession == session.id ? 'selected' : '' }}>{{ session.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="course">{{ 'Courses' | get_lang }}</label>
<div class="controls">
<select name="course" id="course">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for course in courses %}
<option value="{{ course.real_id }}" {{ selectedCourse == course.real_id ? 'selected' : ''}}>{{ course.title }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="month">{{ 'Date' | get_lang }}</label>
<div class="controls">
<select name="month" id="month">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for month in months %}
<option value="{{ month.key }}" {{ selectedMonth == month.key ? 'selected' : ''}}>{{ month.name }}</option>
{% endfor %}
</select>
<input type="text" name="year" id="year" class="input-mini" value="{{ selectedYear }}">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary">{{ 'Search' | get_lang }}</button>
</div>
</div>
</form>
{{ searchBySessionCourseDateForm }}
<hr>
<h1 class="page-header">{{ 'GradebookListOfStudentsCertificates' | get_lang }}</h1>
{{ searchByStudentForm }}
{% if errorMessage is defined %}
<div class="alert alert-error">{{ errorMessage }}</div>
{% endif %}
{% if not certificateStudents is empty %}
<p>
<a href="{{ exportAllLink }}" class="btn btn-info">{{ 'ExportAllCertificatesToPDF' | get_lang }}</a>
</p>
<h2 class="page-header">{{ "GradebookListOfStudentsCertificates" | get_lang }}</h2>
{% if not exportAllLink is null %}
<div class="actions">
<a href="{{ exportAllLink }}" class="btn btn-info">
<i class="fa fa-check"></i> {{ 'ExportAllCertificatesToPDF' | get_lang }}
</a>
</div>
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th>{{ 'Student' | get_lang }}</th>
<th>{{ 'Sesion' | get_lang }}</th>
<th>{{ 'Course' | get_lang }}</th>
<th>{{ 'Date' | get_lang }}</th>
<th>{{ 'Certificate' | get_lang }}</th>
</tr>
@ -94,6 +61,8 @@
<tfoot>
<tr>
<th>{{ 'Student' | get_lang }}</th>
<th>{{ 'Sesion' | get_lang }}</th>
<th>{{ 'Course' | get_lang }}</th>
<th>{{ 'Date' | get_lang }}</th>
<th>{{ 'Certificate' | get_lang }}</th>
</tr>
@ -102,6 +71,8 @@
{% for student in certificateStudents %}
<tr>
<td>{{ student.fullName }}</td>
<td>{{ student.sessionName }}</td>
<td>{{ student.courseName }}</td>
<td>
{% for certificate in student.certificates %}
<p>{{ certificate.createdAt }}</p>

@ -465,6 +465,9 @@ $(function() {
$(".td_actions").parent('tr').mouseout(function() {
$(".td_actions").hide();
});*/
/* Make responsive image maps */
$('map').imageMapResize();
});
</script>
{{ css_custom_file_to_string }}

@ -341,14 +341,14 @@ function open_popup(skill_id, parent_id) {
var parent_info = get_skill_info(skill.extra.parent_id);
if ("{{ isAdministration }}") {
$("#id").attr('value', skill.id);
$("#name").attr('value', skill.name);
$("#short_code").attr('value', skill.short_code);
$("#description").attr('value', skill.description);
$('input[name="id"]').val(skill.id);
$("#name").val(skill.name);
$("#short_code").val(skill.short_code);
$("#description").val(skill.description);
} else {
$("#name").text(skill.name);
$("#short_code").text(skill.short_code);
$("#description").text(skill.description);
$("#name").prop('readonly', true).val(skill.name);
$("#short_code").prop('readonly', true).val(skill.short_code);
$("#description").prop('readonly', true).val(skill.description);
}
// Filling parent_id
@ -364,20 +364,30 @@ function open_popup(skill_id, parent_id) {
if ("{{ isAdministration }}") {
$("#dialog-form").dialog({
buttons: {
"{{ "Save"|get_lang }}": function () {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
buttons: [
{
text: "{{ "Save"|get_lang }}",
class: 'btn btn-primary',
click: function() {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
}
},
/*"{{ "Delete"|get_lang }}" : function() {
},*/
"{{ "CreateChildSkill"|get_lang }}": function () {
open_popup(0, skill.id);
{
text: "{{ "CreateChildSkill"|get_lang }}",
class: 'btn btn-primary',
click: function() {
open_popup(0, skill.id);
}
},
"{{ "AddSkillToProfileSearch"|get_lang }}": function () {
add_skill_in_profile_list(skill.id, skill.name);
{
text: "{{ "AddSkillToProfileSearch"|get_lang }}",
class: 'btn btn-primary',
click: function () {
add_skill_in_profile_list(skill.id, skill.name);
}
}
}
],
});
}
@ -396,7 +406,7 @@ function open_popup(skill_id, parent_id) {
}
if (parent) {
$("#id").attr('value','');
$('input[name="id"]').attr('value','');
$("#name").attr('value', '');
$("#short_code").attr('value', '');
$("#description").attr('value', '');
@ -413,12 +423,16 @@ function open_popup(skill_id, parent_id) {
});
$("#dialog-form").dialog({
buttons: {
"{{ "Save"|get_lang }}" : function() {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
}
},
buttons: [
{
text: "{{ "Save"|get_lang }}",
class: 'btn btn-primary',
click: function() {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
}
}
],
close: function() {
$("#name").attr('value', '');
$("#description").attr('value', '');
@ -651,38 +665,42 @@ function load_nodes(load_skill_id, main_depth, extra_parent_id) {
});
/** Managing text - maximum two words */
var insert_two_words = false;
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) {
if (d.depth && d.name) {
var nameParts = d.name.split(' ');
if (nameParts[0].length > max_size_text_length) {
return nameParts[0].substring(0, max_size_text_length - 3) + '...';
}
return nameParts[0];
}
return d.depth ? d.name : '';
});
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) {
if (d.depth && d.name.length > max_size_text_length) {
if (d.depth) {
first_part = d.name.split(" ")[0];
second_part = d.name.split(" ")[1];
if (first_part.length >= max_size_text_length) {
insert_two_words = false;
return first_part.substring(0, max_size_text_length -3) + ' ... ';
} else {
return first_part;
if (d.depth && d.name) {
var nameParts = d.name.split(' ');
if (nameParts.length >= 2) {
if (nameParts[1].length > max_size_text_length) {
return nameParts[1].substring(0, max_size_text_length - 3) + '...';
}
} else {
return "";
return nameParts[1];
}
} else {
insert_two_words = false;
return d.depth ? d.name : "";
return '';
}
});
if (insert_two_words) {
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) {
return d.depth && d.name.length > max_size_text_length ? d.name.split(" ")[1] || "" : "";
});
}
return d.depth ? d.name : '';
});
/* Icon settings */
/*

@ -280,7 +280,7 @@ $(document).ready(function() {
/* Click in profile */
$("#saved_profiles").on("click", "li.load_profile", function() {
profile_id = $(this).attr('rel');
$('#profile_id').attr('value',profile_id);
$('input[name="profile_id"]').val(profile_id);
$.ajax({
url: '{{ url }}&a=get_skills_by_profile&profile_id='+profile_id,
success:function(json) {
@ -317,7 +317,7 @@ $(document).ready(function() {
/* Close button in gradebook select */
$("#gradebook_holder").on("click", "a.closebutton", function() {
gradebook_id = $(this).attr('rel');
skill_id = $('#id').attr('value');
skill_id = $('input[name="id"]').attr('value');
delete_gradebook_from_skill(skill_id, gradebook_id);
});
@ -364,7 +364,7 @@ $(document).ready(function() {
$("#dialog-form").dialog({
autoOpen: false,
modal : true,
width : 600,
width : 900,
height : 630
});
@ -372,14 +372,14 @@ $(document).ready(function() {
$("#dialog-form-profile").dialog({
autoOpen: false,
modal : true,
width : 500,
width : 850,
height : 400
});
load_nodes(0, main_depth);
function open_save_profile_popup() {
var profileId = $("#profile_id").val();
var profileId = $('input[name="profile_id"]').val();
$.ajax({
url: '{{ url }}&a=get_profile&profile_id='+profileId,
success:function(data) {
@ -392,36 +392,40 @@ $(document).ready(function() {
});
$("#dialog-form-profile").dialog({
buttons: {
"{{ "Save"|get_lang }}" : function() {
var name = $("#name_profile").val();
var description = $("#description_profile").val();
var skill_list = return_skill_list_from_profile_search();
skill_list = { 'skill_id' : skill_list };
skill_params = $.param(skill_list);
$.ajax({
url: '{{ url }}&a=save_profile&name='+name+'&description='+description+'&'+skill_params+'&profile='+profileId,
success:function(data) {
if (data == 1 ) {
update_my_saved_profiles();
alert("{{ "Saved"|get_lang }}");
} else {
alert("{{ "Error"|get_lang }}");
buttons: [
{
text: "{{ "Save"|get_lang }}",
class: 'btn btn-primary',
click: function() {
var name = $("#name_profile").val();
var description = $("#description_profile").val();
var skill_list = return_skill_list_from_profile_search();
skill_list = { 'skill_id' : skill_list };
skill_params = $.param(skill_list);
$.ajax({
url: '{{ url }}&a=save_profile&name='+name+'&description='+description+'&'+skill_params+'&profile='+profileId,
success:function(data) {
if (data == 1 ) {
update_my_saved_profiles();
alert("{{ "Saved"|get_lang }}");
} else {
alert("{{ "Error"|get_lang }}");
}
$("#dialog-form-profile").dialog("close");
$("#name_profile").attr('value', '');
$("#description_profile").attr('value', '');
$('input[name="profile_id"]').val(0);
}
$("#dialog-form-profile").dialog("close");
$("#name_profile").attr('value', '');
$("#description_profile").attr('value', '');
$("#profile_id").attr('value', '0');
}
});
}
},
});
}
}
],
close: function() {
$("#name_profile").attr('value', '');
$("#description_profile").attr('value', '');
$("#profile_id").attr('value', '0');
$("#name_profile").val('');
$("#description_profile").val('');
$('input[name="profile_id"]').val(0);
}
});
$("#dialog-form-profile").dialog("open");
@ -581,76 +585,11 @@ $(document).ready(function() {
<div id="dialog-form" style="">
<p class="validateTips"></p>
<form id="add_item" class="form-horizontal" name="form">
<fieldset>
<input type="hidden" name="id" id="id"/>
<div class="form-group">
<label class="col-sm-2 control-label" for="name">{{ 'Name' | get_lang }}</label>
<div class="col-sm-8">
<input type="text" name="name" id="name" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">{{ 'ShortCode' | get_lang }}</label>
<div class="col-sm-8">
<input type="text" name="short_code" id="short_code" />
</div>
</div>
<div id="skill_row" class="form-group">
<label class="col-sm-2 control-label" for="name">{{'Parent'|get_lang}}</label>
<div class="col-sm-8">
<select id="parent_id" name="parent_id" />
</select>
<ul id="skill_edit_holder" class="holder holder_simple">
</ul>
</div>
</div>
<div id="gradebook_row" class="form-group">
<label class="col-sm-2 control-label" for="name">{{'Gradebook'|get_lang}}</label>
<div class="col-sm-8">
<select id="gradebook_id" name="gradebook_id" multiple="multiple"/>
</select>
<ul id="gradebook_holder" class="holder holder_simple">
</ul>
<span class="help-block">
{{ 'WithCertificate'|get_lang }}
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="name">{{ 'Description'|get_lang }}</label>
<div class="col-sm-8">
<textarea name="description" id="description" rows="7"></textarea>
</div>
</div>
</fieldset>
</form>
{{ dialogForm }}
</div>
<div id="dialog-form-profile" style="display:none;">
<form id="save_profile_form" class="form-horizontal" name="form">
<input type="hidden" id="profile_id" name="profile_id"/>
<fieldset>
<div class="form-group">
<label class="col-sm-2 control-label" for="name">{{"Name"|get_lang}}</label>
<div class="col-sm-8">
<input type="text" name="name" id="name_profile" size="40" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="name">{{"Description"|get_lang}}</label>
<div class="col-sm-8">
<textarea name="description" id="description_profile" rows="7"></textarea>
</div>
</div>
</fieldset>
</form>
{{ saveProfileForm }}
</div>
</div>
</div>

@ -133,7 +133,7 @@ $(document).ready(function() {
/* Close button in gradebook select */
$("#gradebook_holder").on("click", "a.closebutton", function() {
gradebook_id = $(this).attr('rel');
skill_id = $('#id').attr('value');
skill_id = $('input[name="id"]').attr('value');
delete_gradebook_from_skill(skill_id, gradebook_id);
});
@ -180,7 +180,7 @@ $(document).ready(function() {
$("#dialog-form").dialog({
autoOpen: false,
modal : true,
width : 600,
width : 900,
height : 550
});
@ -215,7 +215,7 @@ $(document).ready(function() {
if (skill) {
var parent_info = get_skill_info(skill.extra.parent_id);
$("#id").attr('value', skill.id);
$('input[name="id"]').attr('value', skill.id);
$("#name").attr('value', skill.name);
$("#short_code").attr('value', skill.short_code);
$("#description").attr('value', skill.description);
@ -232,21 +232,30 @@ $(document).ready(function() {
});
$("#dialog-form").dialog({
buttons: {
"{{ "Edit"|get_lang }}" : function() {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
},
/*"{{ "Delete"|get_lang }}" : function() {
},*/
"{{ "CreateChildSkill"|get_lang }}" : function() {
open_popup(0, skill.id);
},
"{{ "AddSkillToProfileSearch"|get_lang }}" : function() {
add_skill_in_profile_list(skill.id, skill.name);
}
},
buttons: [
{
text: "{{ "Edit"|get_lang }}",
class: 'btn btn-primary',
click: function() {
var params = $("#add_item").find(':input').serialize();
add_skill(params);
}
},
{
text: "{{ "CreateChildSkill"|get_lang }}",
class: 'btn btn-primary',
click: function() {
open_popup(0, skill.id);
}
},
{
text: "{{ "AddSkillToProfileSearch"|get_lang }}",
class: 'btn btn-primary',
click: function() {
add_skill_in_profile_list(skill.id, skill.name);
}
}
],
close: function() {
$("#name").attr('value','');
$("#description").attr('value', '');
@ -378,50 +387,5 @@ $(document).ready(function() {
<div id="dialog-form" style="">
<p class="validateTips"></p>
<form id="add_item" class="form-horizontal" name="form">
<fieldset>
<div class="control-group">
<label class="control-label" for="name">{{ 'Name' | get_lang }}</label>
<div class="controls">
<!--<input type="text" name="name" id="name" class="span4" readonly />-->
<p id="name" class="span4">
</p>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ 'ShortCode' | get_lang }}</label>
<div class="controls">
<!--<input type="text" name="short_code" id="short_code" class="span2" readonly />-->
<p id="short_code" class="span4">
</p>
</div>
</div>
<div id="skill_row" class="control-group">
<label class="control-label" for="name">{{'Parent'|get_lang}}</label>
<div class="controls">
<ul id="skill_edit_holder" class="holder holder_simple">
</ul>
</div>
</div>
<div id="gradebook_row" class="control-group">
<label class="control-label" for="name">{{'Gradebook'|get_lang}}</label>
<div class="controls">
<ul id="gradebook_holder" class="holder holder_simple">
</ul>
<span class="help-block">
{{ 'WithCertificate'|get_lang }}
</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="name">{{ 'Description'|get_lang }}</label>
<div class="controls">
<!--<textarea name="description" id="description" class="span4" rows="7" readonly>
</textarea>-->
<p id="description" class="span4">
</p>
</div>
</div>
</fieldset>
</form>
{{ dialogForm }}
</div>

@ -3825,14 +3825,15 @@ function uploadWork($my_folder_data, $_course)
* @param array $courseInfo
* @param int $session_id
*/
function sendAlertToTeacher($workId, $courseInfo, $session_id)
function sendAlertToUsers($workId, $courseInfo, $session_id)
{
$user_list = array();
$workData = get_work_assignment_by_id($workId, $courseInfo['real_id']);
//last value is to check this is not "just" an edit
//YW Tis part serve to send a e-mail to the tutors when a new file is sent
$send = api_get_course_setting('email_alert_manager_on_new_doc');
if ($send > 0) {
if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_TEACHERS) {
// Lets predefine some variables. Be sure to change the from address!
if (empty($session_id)) {
//Teachers
@ -3853,9 +3854,37 @@ function sendAlertToTeacher($workId, $courseInfo, $session_id)
2
);
}
}
$subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']." ";
if ($send == SEND_EMAIL_EVERYONE || $send == SEND_EMAIL_STUDENTS) {
if (!$session_id) {
$session_id = null;
}
$student = CourseManager::get_user_list_from_course_code(
api_get_course_id(),
$session_id,
null,
null,
STUDENT,
null,
null,
null,
null,
null,
array(api_get_user_id())
);
$user_list = array_merge($user_list, $student);
}
if ($send) {
$senderEmail = api_get_setting('emailAdministrator');
$senderName = api_get_person_name(
api_get_setting('administratorName'),
api_get_setting('administratorSurname'),
null,
PERSON_NAME_EMAIL_ADDRESS
);
$subject = "[" . api_get_setting('siteName') . "] ".get_lang('SendMailBody')."\n".get_lang('CourseName')." : ".$courseInfo['name']." ";
foreach ($user_list as $user_data) {
$to_user_id = $user_data['user_id'];
$user_info = api_get_user_info($to_user_id);
@ -3865,8 +3894,19 @@ function sendAlertToTeacher($workId, $courseInfo, $session_id)
$message .= get_lang('WorkName')." : ".$workData['title']."\n\n".get_lang('DownloadLink')."\n";
$url = api_get_path(WEB_CODE_PATH)."work/work.php?cidReq=".$courseInfo['code']."&id_session=".$session_id."&id=".$workData['id'];
$message .= $url;
MessageManager::send_message_simple($to_user_id, $subject, $message);
api_mail_html(
api_get_person_name(
$user_info['firstname'].' '.$user_info['lastname'],
null,
PERSON_NAME_EMAIL_ADDRESS
),
$user_info['email'],
$subject,
$message,
$senderName,
$senderEmail
);
}
}
}
@ -3958,7 +3998,7 @@ function processWorkForm($workInfo, $values, $courseInfo, $sessionId, $groupId,
$userId,
$groupId
);
sendAlertToTeacher($workId, $courseInfo, $sessionId);
sendAlertToUsers($workId, $courseInfo, $sessionId);
Event::event_upload($workId);
$message = Display::return_message(get_lang('DocAdd'));
}

@ -31,13 +31,17 @@ class HookResubscription extends HookObserver implements HookResubscribeObserver
$resubscriptionLimit = Resubscription::create()->get('resubscription_limit');
$limitDate = gmdate('Y-m-d');
// Initialize variables as a calendar year by default
$limitDateFormat = 'Y-01-01';
$limitDate = gmdate($limitDateFormat);
$resubscriptionOffset = "1 year";
switch ($resubscriptionLimit) {
case 'calendar_year':
$resubscriptionLimit = "1 year";
$limitDate = gmdate('Y-m-d', strtotime(gmdate('Y-m-d')." -$resubscriptionLimit"));
break;
// No need to use a 'switch' with only two options so an 'if' is enough.
// However this could change if the number of options increases
if ($resubscriptionLimit === 'natural_year') {
$limitDateFormat = 'Y-m-d';
$limitDate = gmdate($limitDateFormat);
$limitDate = gmdate($limitDateFormat, strtotime("$limitDate -$resubscriptionOffset"));
}
$join = " INNER JOIN ".Database::get_main_table(TABLE_MAIN_SESSION)."ON id = id_session";
@ -94,7 +98,7 @@ class HookResubscription extends HookObserver implements HookResubscribeObserver
foreach ($currentSessionCourseResult as $currentSessionCourse) {
if (isset($userSessionCourses[$currentSessionCourse['course_code']])) {
$endDate = $userSessionCourses[$currentSessionCourse['course_code']];
$resubscriptionDate = gmdate('Y-m-d', strtotime($endDate." +$resubscriptionLimit"));
$resubscriptionDate = gmdate($limitDateFormat, strtotime($endDate." +$resubscriptionOffset"));
$icon = Display::return_icon('students.gif', get_lang('Student'));
$canResubscribeFrom = sprintf(get_plugin_lang('CanResubscribeFromX', 'resubscription'), $resubscriptionDate);
throw new Exception(Display::label($icon . ' ' . $canResubscribeFrom, "info"));

@ -16,7 +16,8 @@ class Resubscription extends Plugin implements HookPluginInterface
protected function __construct()
{
$options = array(
'calendar_year' => get_lang('CalendarYear')
'calendar_year' => get_lang('CalendarYear'),
'natural_year' => get_lang('NaturalYear')
);
$parameters = array(
'resubscription_limit' => array(
@ -24,7 +25,6 @@ class Resubscription extends Plugin implements HookPluginInterface
'options' => $options
)
);
parent::__construct('0.1', 'Imanol Losada Oriol', $parameters);
}

@ -0,0 +1,71 @@
<?php
/**
* Move user fields "ruc" and "razon_social" to (social) groups (create groups)
* and assign the related users to those groups.
*/
if (PHP_SAPI != 'cli') {
die('This script can only be launched from the command line');
}
require __DIR__ . '/../../main/inc/global.inc.php';
// We assume all these fields represent the same value, so they are on a 1-1
// relationship.
$referenceFields = array('razon_social', 'ruc');
$tUserField = Database::get_main_table(TABLE_MAIN_USER_FIELD);
$tUserFieldValue = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
$tUser = Database::get_main_table(TABLE_MAIN_USER);
$tGroup = Database::get_main_table(TABLE_MAIN_GROUP);
$tGroupUser = Database::get_main_table(TABLE_MAIN_USER_REL_GROUP);
// First get the IDs of the selected fields
$sql = "SELECT id, field_type, field_variable FROM $tUserField";
$result = Database::query($sql);
$foundFields = array();
$fieldsNames = array();
while ($row = Database::fetch_assoc($result)) {
if ($row['field_type'] == 1 && in_array($row['field_variable'], $referenceFields)) {
$foundFields[$row['field_variable']] = array('id' => $row['id']);
$fieldsNames[$row['id']] = $row['field_variable'];
}
}
// Second get all the possible values of this field (in user data)
$usersData = array();
foreach ($foundFields as $key => $value) {
$sql = "SELECT user_id, field_value FROM $tUserFieldValue WHERE field_id = " . $value['id'];
$result = Database::query($sql);
while ($row = Database::fetch_assoc($result)) {
$foundFields[$key]['options'][$row['field_value']][] = $row['user_id'];
if (empty($usersData[$row['user_id']])) {
$usersData[$row['user_id']] = '';
}
if ($referenceFields[0] == $key) {
$usersData[$row['user_id']] = $row['field_value'] . ' - ' . $usersData[$row['user_id']];
} else {
$usersData[$row['user_id']] .= $row['field_value'] . ' - ';
}
}
}
// Clean the user string
$distinctGroups = array();
foreach ($usersData as $userId => $value) {
$usersData[$userId] = substr($usersData[$userId], 0, -3);
$distinctGroups[$usersData[$userId]][] = $userId;
}
// Third, we create groups based on the combined strings by user and insert
// users in them (as reader)
foreach ($distinctGroups as $name => $usersList) {
$now = api_get_utc_datetime();
$sql = "INSERT INTO $tGroup (name, visibility, updated_on, created_on) VALUES ('$name', 1, '$now', '$now')";
echo $sql . PHP_EOL;
$result = Database::query($sql);
$groupId = Database::insert_id();
echo $groupId . PHP_EOL;
foreach ($usersList as $user) {
$sql = "INSERT INTO $tGroupUser (group_id, user_id, relation_type) VALUES ($groupId, $user, 2)";
echo $sql . PHP_EOL;
$result = Database::query($sql);
}
}
Loading…
Cancel
Save