Skip to content

Commit b1f8c25

Browse files
Merge pull request #6245 from christianbeeznest/GH-6134
Internal: Add tracking to all resource event - refs #6134
2 parents 65453d7 + c7d4f6a commit b1f8c25

17 files changed

+325
-73
lines changed

assets/vue/services/linkService.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ export default {
6868
*/
6969
toggleLinkVisibility: async (linkId, visible, cid, sid) => {
7070
const endpoint = `${ENTRYPOINT}links/${linkId}/toggle_visibility?cid=${cid}&sid=${sid}`
71-
72-
return baseService.put(endpoint, { visible })
71+
const response = await axios.put(endpoint, { visible })
72+
return response.data
7373
},
7474

7575
/**

assets/vue/views/links/LinksList.vue

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ const categoryToDelete = ref(null)
217217
const isLoading = ref(true)
218218
219219
const linkValidationResults = ref({})
220+
const isToggling = ref({})
220221
221222
onMounted(async () => {
222223
isAllowedToEdit.value = await checkIsAllowedToEdit(true, true, true)
@@ -266,17 +267,28 @@ async function checkLink(id, url) {
266267
}
267268
268269
async function toggleVisibility(link) {
270+
if (isToggling.value[link.iid]) return
271+
isToggling.value = { ...isToggling.value, [link.iid]: true }
272+
269273
try {
270-
const visibility = toggleVisibilityProperty(!link.linkVisible)
271-
let newLink = await linkService.toggleLinkVisibility(link.iid, isVisible(visibility), cid, sid)
272-
notifications.showSuccessNotification(t("Link visibility updated"))
273-
Object.values(categories.value)
274-
.map((c) => c.links)
275-
.flat()
274+
const newVisible = !isVisible(link.linkVisible)
275+
const updatedLink = await linkService.toggleLinkVisibility(link.iid, newVisible, cid, sid)
276+
const newFlagValue = visibilityFromBoolean(updatedLink.linkVisible)
277+
278+
linksWithoutCategory.value
276279
.filter((l) => l.iid === link.iid)
277-
.forEach((l) => (l.linkVisible = visibilityFromBoolean(newLink.linkVisible)))
278-
} catch (error) {
280+
.forEach((l) => (l.linkVisible = newFlagValue))
281+
282+
categories.value
283+
.flatMap((c) => c.links || [])
284+
.filter((l) => l.iid === link.iid)
285+
.forEach((l) => (l.linkVisible = newFlagValue))
286+
287+
notifications.showSuccessNotification(t("Link visibility updated"))
288+
} catch (err) {
279289
notifications.showErrorNotification(t("Could not change visibility of link"))
290+
} finally {
291+
isToggling.value = { ...isToggling.value, [link.iid]: false }
280292
}
281293
}
282294

public/main/exercise/exercise.class.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Chamilo\CoreBundle\Entity\TrackEHotspot;
1111
use Chamilo\CoreBundle\Framework\Container;
1212
use Chamilo\CoreBundle\Repository\ResourceLinkRepository;
13+
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository;
1314
use Chamilo\CourseBundle\Entity\CQuizCategory;
1415
use Chamilo\CourseBundle\Entity\CQuiz;
1516
use Chamilo\CourseBundle\Entity\CQuizRelQuestionCategory;
@@ -1851,6 +1852,21 @@ public function delete()
18511852
GradebookUtils::remove_resource_from_course_gradebook($linkInfo['id']);
18521853
}
18531854

1855+
// Register resource deletion manually because this is a soft delete (active = -1)
1856+
// and Doctrine does not trigger postRemove in this case.
1857+
/* @var TrackEDefaultRepository $trackRepo */
1858+
$trackRepo = Container::$container->get(TrackEDefaultRepository::class);
1859+
$resourceNode = $exercise->getResourceNode();
1860+
if ($resourceNode) {
1861+
$trackRepo->registerResourceEvent(
1862+
$resourceNode,
1863+
'deletion',
1864+
api_get_user_id(),
1865+
api_get_course_int_id(),
1866+
api_get_session_id()
1867+
);
1868+
}
1869+
18541870
return true;
18551871
}
18561872

public/main/forum/forumfunction.inc.php

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Chamilo\CoreBundle\Entity\Session as SessionEntity;
1010
use Chamilo\CoreBundle\Entity\User;
1111
use Chamilo\CoreBundle\Framework\Container;
12+
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository;
1213
use Chamilo\CourseBundle\Entity\CForum;
1314
use Chamilo\CourseBundle\Entity\CForumAttachment;
1415
use Chamilo\CourseBundle\Entity\CForumCategory;
@@ -131,7 +132,7 @@ function handleForum($url)
131132
if ('visible' === $action) {
132133
$repo->setVisibilityPublished($resource, $course, $session);
133134
} else {
134-
$repo->setVisibilityPending($resource);
135+
$repo->setVisibilityPending($resource, $course, $session);
135136
}
136137

137138
if ('visible' === $action) {
@@ -149,6 +150,13 @@ function handleForum($url)
149150
if ($resource) {
150151
$linksRepo->removeByResourceInContext($resource, $course, $session);
151152

153+
// Manually register thread deletion event because the resource is not removed via Doctrine
154+
$trackRepo = Container::$container->get(TrackEDefaultRepository::class);
155+
$node = $resource->getResourceNode();
156+
if ($node) {
157+
$trackRepo->registerResourceEvent($node, 'deletion', api_get_user_id(), api_get_course_int_id(), api_get_session_id());
158+
}
159+
152160
Display::addFlash(
153161
Display::return_message(get_lang('Forum category deleted'), 'confirmation', false)
154162
);
@@ -160,6 +168,13 @@ function handleForum($url)
160168
if ($resource) {
161169
$linksRepo->removeByResourceInContext($resource, $course, $session);
162170

171+
// Register forum deletion manually as it's not deleted via Doctrine
172+
$trackRepo = Container::$container->get(TrackEDefaultRepository::class);
173+
$node = $resource->getResourceNode();
174+
if ($node) {
175+
$trackRepo->registerResourceEvent($node, 'deletion', api_get_user_id(), api_get_course_int_id(), api_get_session_id());
176+
}
177+
163178
Display::addFlash(Display::return_message(get_lang('Forum deleted'), 'confirmation', false));
164179
}
165180

@@ -183,6 +198,14 @@ function handleForum($url)
183198
$link_id = $link_info['id'];
184199
GradebookUtils::remove_resource_from_course_gradebook($link_id);
185200
}
201+
202+
// Manually register thread deletion event because the resource is not removed via Doctrine
203+
$trackRepo = Container::$container->get(TrackEDefaultRepository::class);
204+
$node = $resource->getResourceNode();
205+
if ($node) {
206+
$trackRepo->registerResourceEvent($node, 'deletion', api_get_user_id(), api_get_course_int_id(), api_get_session_id());
207+
}
208+
186209
Display::addFlash(Display::return_message(get_lang('Thread deleted'), 'confirmation', false));
187210
}
188211

@@ -856,22 +879,34 @@ function deletePost(CForumPost $post): void
856879
$em->remove($post);
857880
$em->flush();
858881

859-
$lastPostOfTheTread = getLastPostOfThread($post->getThread()->getIid());
882+
$threadId = $post->getThread()->getIid();
883+
$lastPostOfTheTread = getLastPostOfThread($threadId);
860884

861885
if (!empty($lastPostOfTheTread)) {
862-
// Decreasing the number of replies for this thread and also changing the last post information.
863-
$sql = "UPDATE $table_threads
864-
SET
865-
thread_replies = thread_replies - 1,
866-
thread_last_post = ".$lastPostOfTheTread['iid'].",
867-
thread_date = '".$lastPostOfTheTread['post_date']."'
868-
WHERE iid = ".$post->getThread()->getIid();
886+
// Decreasing the number of replies only if > 0
887+
$threadReplies = Database::fetch_array(Database::query("SELECT thread_replies FROM $table_threads WHERE iid = $threadId"));
888+
$replyCount = (int) $threadReplies['thread_replies'];
889+
890+
if ($replyCount > 0) {
891+
$sql = "UPDATE $table_threads
892+
SET
893+
thread_replies = thread_replies - 1,
894+
thread_last_post = ".$lastPostOfTheTread['iid'].",
895+
thread_date = '".$lastPostOfTheTread['post_date']."'
896+
WHERE iid = $threadId";
897+
} else {
898+
$sql = "UPDATE $table_threads
899+
SET
900+
thread_last_post = ".$lastPostOfTheTread['iid'].",
901+
thread_date = '".$lastPostOfTheTread['post_date']."'
902+
WHERE iid = $threadId";
903+
}
904+
869905
Database::query($sql);
870906
Display::addFlash(Display::return_message(get_lang('Post has been deleted')));
871907
} else {
872908
// We deleted the very last post of the thread, so we need to delete the thread as well.
873-
$sql = "DELETE FROM $table_threads
874-
WHERE iid = ".$post->getThread()->getIid();
909+
$sql = "DELETE FROM $table_threads WHERE iid = $threadId";
875910
Database::query($sql);
876911

877912
Display::addFlash(Display::return_message(get_lang('Thread deleted')));
@@ -3138,22 +3173,24 @@ function updateThreadInfo($threadId, $lastPostId, $post_date)
31383173
Database::query($sql);
31393174
}
31403175

3141-
function approvePost(CForumPost $post, $action)
3176+
function approvePost(CForumPost $post, $action): string
31423177
{
31433178
if ('invisible' === $action) {
31443179
$visibility = 0;
3180+
$message = 'PostMadeInvisible';
31453181
}
31463182

31473183
if ('visible' === $action) {
31483184
$visibility = 1;
31493185
handle_mail_cue('post', $post->getIid());
3186+
$message = 'PostMadeVisible';
31503187
}
31513188

31523189
$post->setVisible($visibility);
31533190
Database::getManager()->persist($post);
31543191
Database::getManager()->flush();
31553192

3156-
Display::addFlash(Display::return_message(get_lang('The visibility has been changed')));
3193+
return $message;
31573194
}
31583195

31593196
/**

public/main/lp/learnpath.class.php

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Chamilo\CoreBundle\Entity\Session as SessionEntity;
1010
use Chamilo\CoreBundle\Event\Events;
1111
use Chamilo\CoreBundle\Event\LearningPathEndedEvent;
12+
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository;
1213
use Chamilo\CoreBundle\ServiceHelper\ThemeHelper;
1314
use Chamilo\CourseBundle\Entity\CLpRelUser;
1415
use Chamilo\CoreBundle\Framework\Container;
@@ -793,33 +794,6 @@ public function delete($courseInfo = null, $id = null, $delete = 'keep')
793794

794795
$course = api_get_course_entity();
795796
$session = api_get_session_entity();
796-
797-
//$lp_item = Database::get_course_table(TABLE_LP_ITEM);
798-
//$lp_view = Database::get_course_table(TABLE_LP_VIEW);
799-
//$lp_item_view = Database::get_course_table(TABLE_LP_ITEM_VIEW);
800-
801-
// Delete lp item id.
802-
//foreach ($this->items as $lpItemId => $dummy) {
803-
// $sql = "DELETE FROM $lp_item_view
804-
// WHERE lp_item_id = '".$lpItemId."'";
805-
// Database::query($sql);
806-
//}
807-
808-
// Proposed by Christophe (nickname: clefevre)
809-
//$sql = "DELETE FROM $lp_item
810-
// WHERE lp_id = ".$this->lp_id;
811-
//Database::query($sql);
812-
813-
//$sql = "DELETE FROM $lp_view
814-
// WHERE lp_id = ".$this->lp_id;
815-
//Database::query($sql);
816-
817-
//$table = Database::get_course_table(TABLE_LP_REL_USERGROUP);
818-
//$sql = "DELETE FROM $table
819-
// WHERE
820-
// lp_id = {$this->lp_id}";
821-
//Database::query($sql);
822-
823797
$lp = Container::getLpRepository()->find($this->lp_id);
824798

825799
Database::getManager()
@@ -837,9 +811,17 @@ public function delete($courseInfo = null, $id = null, $delete = 'keep')
837811
GradebookUtils::remove_resource_from_course_gradebook($link_info['id']);
838812
}
839813

840-
//if ('true' === api_get_setting('search_enabled')) {
841-
// delete_all_values_for_item($this->cc, TOOL_LEARNPATH, $this->lp_id);
842-
//}
814+
$trackRepo = Container::$container->get(TrackEDefaultRepository::class);
815+
$resourceNode = $lp->getResourceNode();
816+
if ($resourceNode) {
817+
$trackRepo->registerResourceEvent(
818+
$resourceNode,
819+
'deletion',
820+
api_get_user_id(),
821+
api_get_course_int_id(),
822+
api_get_session_id()
823+
);
824+
}
843825
}
844826

845827
/**

src/CoreBundle/Controller/Api/UpdateDocumentFileAction.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,33 @@
66

77
namespace Chamilo\CoreBundle\Controller\Api;
88

9+
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository;
910
use Chamilo\CourseBundle\Entity\CDocument;
1011
use Chamilo\CourseBundle\Repository\CDocumentRepository;
1112
use Doctrine\ORM\EntityManager;
13+
use Symfony\Bundle\SecurityBundle\Security;
1214
use Symfony\Component\HttpFoundation\Request;
1315

1416
class UpdateDocumentFileAction extends BaseResourceFileAction
1517
{
18+
public function __construct(
19+
private TrackEDefaultRepository $trackRepo,
20+
private Security $security
21+
) {}
22+
1623
public function __invoke(CDocument $document, Request $request, CDocumentRepository $repo, EntityManager $em): CDocument
1724
{
1825
$this->handleUpdateRequest($document, $repo, $request, $em);
1926

27+
$node = $document->getResourceNode();
28+
if ($node) {
29+
$this->trackRepo->registerResourceEvent(
30+
$node,
31+
'edition',
32+
$this->security->getUser()?->getId()
33+
);
34+
}
35+
2036
return $document;
2137
}
2238
}

src/CoreBundle/Controller/Api/UpdateVisibilityDocument.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,37 @@
66

77
namespace Chamilo\CoreBundle\Controller\Api;
88

9+
use Chamilo\CoreBundle\Entity\Course;
10+
use Chamilo\CoreBundle\Entity\Session;
911
use Chamilo\CoreBundle\ServiceHelper\CidReqHelper;
1012
use Chamilo\CourseBundle\Entity\CDocument;
1113
use Chamilo\CourseBundle\Repository\CDocumentRepository;
1214
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1315
use Symfony\Component\HttpKernel\Attribute\AsController;
16+
use Doctrine\ORM\EntityManagerInterface;
1417

1518
#[AsController]
1619
class UpdateVisibilityDocument extends AbstractController
1720
{
1821
public function __construct(
1922
private readonly CidReqHelper $cidReqHelper,
23+
private readonly EntityManagerInterface $em,
2024
) {}
2125

2226
public function __invoke(CDocument $document, CDocumentRepository $repo): CDocument
2327
{
24-
$repo->toggleVisibilityPublishedDraft(
25-
$document,
26-
$this->cidReqHelper->getCourseEntity(),
27-
$this->cidReqHelper->getSessionEntity()
28-
);
28+
$course = $this->cidReqHelper->getCourseEntity();
29+
$session = $this->cidReqHelper->getSessionEntity();
30+
31+
if ($course) {
32+
$course = $this->em->getRepository(Course::class)->find($course->getId());
33+
}
34+
35+
if ($session) {
36+
$session = $this->em->getRepository(Session::class)->find($session->getId());
37+
}
38+
39+
$repo->toggleVisibilityPublishedDraft($document, $course, $session);
2940

3041
return $document;
3142
}

src/CoreBundle/Controller/Api/UpdateVisibilityLink.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public function __invoke(CLink $link, CLinkRepository $repo): CLink
2323
{
2424
$repo->toggleVisibilityPublishedDraft(
2525
$link,
26-
$this->cidReqHelper->getCourseEntity(),
27-
$this->cidReqHelper->getSessionEntity()
26+
$this->cidReqHelper->getDoctrineCourseEntity(),
27+
$this->cidReqHelper->getDoctrineSessionEntity()
2828
);
2929
$link->toggleVisibility();
3030

src/CoreBundle/Controller/Api/UpdateVisibilityLinkCategory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public function __invoke(CLinkCategory $linkCategory, CLinkCategoryRepository $r
2323
{
2424
$repo->toggleVisibilityPublishedDraft(
2525
$linkCategory,
26-
$this->cidReqHelper->getCourseEntity(),
27-
$this->cidReqHelper->getSessionEntity()
26+
$this->cidReqHelper->getDoctrineCourseEntity(),
27+
$this->cidReqHelper->getDoctrineSessionEntity()
2828
);
2929
$linkCategory->toggleVisibility();
3030

0 commit comments

Comments
 (0)