Skip to content

Commit f2bc514

Browse files
committed
Merge branch 'master' of github.com:chamilo/chamilo-lms
2 parents 5613d4f + 566d200 commit f2bc514

File tree

3 files changed

+169
-30
lines changed

3 files changed

+169
-30
lines changed

public/main/announcements/announcements.php

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,21 @@
404404

405405
$to = [];
406406
if (empty($group_id)) {
407+
if (!empty($sessionId)) {
408+
$userGroups = Container::getUsergroupRepository()->findBySession($session);
409+
$groupSelectTitle = get_lang('Classes of session').' '.$session->getTitle();
410+
} else {
411+
$userGroups = Container::getUsergroupRepository()->findByCourse($course);
412+
$groupSelectTitle = get_lang('Classes of course');
413+
}
414+
415+
if (!empty($userGroups)) {
416+
$groupSelect = ['' => get_lang('Select a class')];
417+
foreach ($userGroups as $group) {
418+
$groupSelect[$group->getId()] = $group->getTitle();
419+
}
420+
$form->addSelect('usergroup_id', $groupSelectTitle, $groupSelect, ['id' => 'usergroup_id']);
421+
}
407422
if (isset($_GET['remind_inactive'])) {
408423
$email_ann = '1';
409424
$content_to_modify = sprintf(
@@ -508,41 +523,88 @@
508523
}
509524

510525
$ajaxUrl = api_get_path(WEB_AJAX_PATH).'announcement.ajax.php?'.api_get_cidreq().'&a=preview';
511-
526+
$ajaxUserGroupUrl = api_get_path(WEB_AJAX_PATH).'usergroup.ajax.php?'.api_get_cidreq();
512527
$form->addHtml("
513-
<script>
514-
$(function () {
515-
$('#announcement_preview').on('click', function() {
528+
<script>
529+
$(function () {
530+
$('#usergroup_id').on('change', function () {
531+
const groupId = $(this).val();
532+
const selected = $('#users_to');
533+
selected.empty();
534+
if (!groupId) return;
535+
$.ajax({
536+
url: '".$ajaxUserGroupUrl."',
537+
type: 'POST',
538+
data: {
539+
a: 'get_users_by_group_course',
540+
group_id: groupId,
541+
course_code: '".api_get_course_id()."',
542+
session_id: '".api_get_session_id()."'
543+
},
544+
success: function (response) {
545+
const result = JSON.parse(response);
546+
for (let user of result) {
547+
selected.append(new Option(user.name, 'USER:' + user.id));
548+
}
549+
$('#announcement_preview_result').html('');
550+
}
551+
})
552+
});
553+
554+
$('#announcement_preview').on('click', function () {
555+
const selectedClass = $('#usergroup_id').val();
556+
if (selectedClass) {
516557
var users = [];
517-
$('#users_to option').each(function() {
558+
var userLabels = [];
559+
$('#users_to option').each(function () {
518560
users.push($(this).val());
561+
userLabels.push($(this).text());
519562
});
520-
563+
if (users.length === 0) {
564+
$('#announcement_preview_result').html('');
565+
$('#announcement_preview_result').show();
566+
return;
567+
}
568+
var resultHtml = '<strong>".addslashes(get_lang('Announcement will be sent to'))."</strong><ul>';
569+
userLabels.forEach(function (name) {
570+
resultHtml += '<li>' + name + '</li>';
571+
});
572+
resultHtml += '</ul>';
573+
$('#announcement_preview_result').html(resultHtml);
574+
$('#announcement_preview_result').show();
575+
$('#send_button').show();
576+
} else {
577+
var users = [];
521578
var form = $('#announcement').serialize();
579+
$('#users_to option').each(function () {
580+
users.push($(this).val());
581+
});
522582
$.ajax({
523583
type: 'POST',
524584
dataType: 'json',
525-
url: '".$ajaxUrl."',
526-
data: {users : JSON.stringify(users), form: form},
527-
beforeSend: function() {
585+
url: '" . $ajaxUrl . "',
586+
data: {users: JSON.stringify(users), form: form},
587+
beforeSend: function () {
528588
$('#announcement_preview_result').html('<i class=\"fa fa-spinner\"></i>');
529589
$('#send_button').hide();
530590
},
531-
success: function(result) {
532-
var resultToString = '';
533-
$.each(result, function(index, value) {
534-
resultToString += '&nbsp;' + value;
535-
});
536-
$('#announcement_preview_result').html('' +
537-
'".addslashes(get_lang('Announcement will be sent to'))."<br/>' + resultToString
591+
success: function (result) {
592+
let list = '<ul>';
593+
for (let name of result) {
594+
list += '<li>' + name + '</li>';
595+
}
596+
list += '</ul>';
597+
$('#announcement_preview_result').html(
598+
'<strong>".addslashes(get_lang('Announcement will be sent to'))."</strong><br>' + list
538599
);
539600
$('#announcement_preview_result').show();
540601
$('#send_button').show();
541602
}
542603
});
543-
});
604+
}
544605
});
545-
</script>
606+
});
607+
</script>
546608
");
547609

548610
if (isset($defaults['users'])) {
@@ -671,8 +733,7 @@
671733
$notificationPeriod = $data['notification_period'] ?? [];
672734

673735
$reminders = $notificationCount ? array_map(null, $notificationCount, $notificationPeriod) : [];
674-
675-
if (isset($id) && $id) {
736+
if (!empty($id)) {
676737
// there is an Id => the announcement already exists => update mode
677738
$file_comment = $announcementAttachmentIsDisabled ? null : $_POST['file_comment'];
678739
$file = $announcementAttachmentIsDisabled ? [] : $_FILES['user_upload'];

public/main/inc/ajax/usergroup.ajax.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,47 @@
55
/**
66
* Responses to AJAX calls.
77
*/
8+
9+
use Chamilo\CoreBundle\Framework\Container;
10+
811
require_once __DIR__.'/../global.inc.php';
912

1013
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
1114
$isAllowedToEdit = api_is_allowed_to_edit();
1215

1316
switch ($action) {
17+
case 'get_users_by_group_course':
18+
$groupId = (int) $_POST['group_id'];
19+
$sessionId = (int) $_POST['session_id'];
20+
if ($groupId) {
21+
$users = Container::getUsergroupRepository()->getUsersByGroup($groupId, true);
22+
if (!empty($sessionId)) {
23+
$filtered = [];
24+
foreach ($users as $user) {
25+
$filtered[] = [
26+
'id' => $user['id'],
27+
'name' => api_get_person_name($user['firstname'], $user['lastname']),
28+
];
29+
}
30+
} else {
31+
$courseCode = $_POST['course_code'];
32+
$courseUsers = CourseManager::get_user_list_from_course_code($courseCode, 0);
33+
$courseUserIds = array_column($courseUsers, 'user_id');
34+
35+
$filtered = [];
36+
foreach ($users as $user) {
37+
if (in_array($user['id'], $courseUserIds)) {
38+
$filtered[] = [
39+
'id' => $user['id'],
40+
'name' => api_get_person_name($user['firstname'], $user['lastname']),
41+
];
42+
}
43+
}
44+
}
45+
46+
echo json_encode($filtered);
47+
}
48+
exit;
1449
case 'get_class_by_keyword':
1550
$keyword = isset($_REQUEST['q']) ? $_REQUEST['q'] : '';
1651
if (api_is_platform_admin() && !empty($keyword)) {

src/CoreBundle/Repository/Node/UsergroupRepository.php

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Chamilo\CoreBundle\Repository\Node;
88

9+
use Chamilo\CoreBundle\Entity\Course;
10+
use Chamilo\CoreBundle\Entity\Session;
911
use Chamilo\CoreBundle\Entity\User;
1012
use Chamilo\CoreBundle\Entity\Usergroup;
1113
use Chamilo\CoreBundle\Entity\UsergroupRelUser;
@@ -24,6 +26,41 @@ public function __construct(
2426
parent::__construct($registry, Usergroup::class);
2527
}
2628

29+
public function findBySession(Session $session, bool $checkAccessUrl = false): array
30+
{
31+
$qb = $this->createQueryBuilder('ug')
32+
->innerJoin('ug.sessions', 'ugs')
33+
->where('ugs.session = :session')
34+
->setParameter('session', $session);
35+
36+
if ($checkAccessUrl && $this->accessUrlHelper->isMultiple()) {
37+
$accessUrl = $this->accessUrlHelper->getCurrent();
38+
$qb->innerJoin('ug.urls', 'url')
39+
->andWhere('url.url = :urlId')
40+
->setParameter('urlId', $accessUrl->getId());
41+
}
42+
43+
return $qb->getQuery()->getResult();
44+
}
45+
46+
public function findByCourse(Course $course, bool $checkAccessUrl = false): array
47+
{
48+
$qb = $this->createQueryBuilder('ug')
49+
->innerJoin('ug.courses', 'ugc')
50+
->where('ugc.course = :course')
51+
->setParameter('course', $course);
52+
53+
if ($checkAccessUrl && $this->accessUrlHelper->isMultiple()) {
54+
$accessUrl = $this->accessUrlHelper->getCurrent();
55+
56+
$qb->innerJoin('ug.urls', 'url')
57+
->andWhere('url.url = :urlId')
58+
->setParameter('urlId', $accessUrl->getId());
59+
}
60+
61+
return $qb->getQuery()->getResult();
62+
}
63+
2764
/**
2865
* @param int|array $relationType
2966
*/
@@ -156,21 +193,27 @@ public function searchGroups(string $searchTerm): array
156193
return $queryBuilder->getQuery()->getResult();
157194
}
158195

159-
public function getUsersByGroup(int $groupID)
196+
public function getUsersByGroup(int $groupID, bool $includeNormalClass = false): array
160197
{
161198
$qb = $this->createQueryBuilder('g')
162199
->innerJoin('g.users', 'gu')
163200
->innerJoin('gu.user', 'u')
164201
->where('g.id = :groupID')
165-
->setParameter('groupID', $groupID)
166-
->andWhere('gu.relationType IN (:relationTypes)')
167-
->setParameter('relationTypes', [
168-
Usergroup::GROUP_USER_PERMISSION_ADMIN,
169-
Usergroup::GROUP_USER_PERMISSION_READER,
170-
Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION,
171-
])
172-
->select('u.id, u.username, u.email, gu.relationType, u.pictureUri')
173-
;
202+
->setParameter('groupID', $groupID);
203+
204+
$relationTypes = [
205+
Usergroup::GROUP_USER_PERMISSION_ADMIN,
206+
Usergroup::GROUP_USER_PERMISSION_READER,
207+
Usergroup::GROUP_USER_PERMISSION_PENDING_INVITATION,
208+
];
209+
210+
if ($includeNormalClass) {
211+
$relationTypes[] = 0;
212+
}
213+
214+
$qb->andWhere('gu.relationType IN (:relationTypes)')
215+
->setParameter('relationTypes', $relationTypes)
216+
->select('u.id, u.username, u.email, gu.relationType, u.pictureUri, u.firstname, u.lastname');
174217

175218
$results = $qb->getQuery()->getResult();
176219

0 commit comments

Comments
 (0)