Passed
Pull Request — master (#6896)
by
unknown
08:56
created

DocumentUsageAction   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 76
c 2
b 0
f 0
dl 0
loc 156
rs 10
wmc 24

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 46 3
B processUserDocuments() 0 28 8
A __construct() 0 6 1
A processCourseSessions() 0 17 4
A calculatePercentage() 0 7 2
A calculateSessionTotalQuota() 0 10 2
A processCourseGroups() 0 17 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chamilo\CoreBundle\Controller\Api;
6
7
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
8
use Chamilo\CoreBundle\Repository\SessionRepository;
9
use Chamilo\CourseBundle\Repository\CDocumentRepository;
10
use Chamilo\CourseBundle\Repository\CGroupRepository;
11
use DocumentManager;
12
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
13
use Symfony\Component\HttpFoundation\JsonResponse;
14
use Symfony\Component\HttpKernel\Attribute\AsController;
15
16
#[AsController]
17
class DocumentUsageAction extends AbstractController
18
{
19
    public function __construct(
20
        private readonly CourseRepository $courseRepository,
21
        private readonly CDocumentRepository $documentRepository,
22
        private readonly CGroupRepository $groupRepository,
23
        private readonly SessionRepository $sessionRepository,
24
    ) {}
25
26
    public function __invoke($cid): JsonResponse
27
    {
28
        $courseId = (int) $cid;
29
        $sessionId = api_get_session_id();
30
        $groupId = api_get_group_id();
31
32
        $courseEntity = $this->courseRepository->find($courseId);
33
        if (!$courseEntity) {
34
            return new JsonResponse(['error' => 'Course not found'], 404);
35
        }
36
37
        $sessionEntity = api_get_session_entity();
38
39
        $totalQuotaBytes = ($courseEntity->getDiskQuota() * 1024 * 1024) ?? DEFAULT_DOCUMENT_QUOTA;
40
        $usedQuotaBytes = $this->documentRepository->getTotalSpaceByCourse($courseEntity);
41
42
        $chartData = [];
43
44
        // Process sessions
45
        $this->processCourseSessions($courseEntity, $sessionId, $totalQuotaBytes, $usedQuotaBytes, $chartData);
46
47
        // Process groups
48
        $this->processCourseGroups($courseEntity, $groupId, $totalQuotaBytes, $usedQuotaBytes, $chartData);
49
50
        // Process user documents
51
        $users = $this->courseRepository->getUsersByCourse($courseEntity);
52
        foreach ($users as $user) {
53
            $userId = $user->getId();
54
            $userName = $user->getFullName();
55
            $this->processUserDocuments($courseEntity, $sessionEntity, $userId, $userName, $totalQuotaBytes, $chartData);
56
        }
57
58
        // Add available space
59
        $availableBytes = $totalQuotaBytes - $usedQuotaBytes;
60
        $availablePercentage = $this->calculatePercentage($availableBytes, $totalQuotaBytes);
61
62
        $chartData[] = [
63
            'label' => addslashes(get_lang('Available space')).' ('.format_file_size($availableBytes).')',
64
            'percentage' => $availablePercentage,
65
        ];
66
67
        return new JsonResponse([
68
            'datasets' => [
69
                ['data' => array_column($chartData, 'percentage')],
70
            ],
71
            'labels' => array_column($chartData, 'label'),
72
        ]);
73
    }
74
75
    private function processCourseSessions($courseEntity, int $sessionId, int $totalQuotaBytes, int &$usedQuotaBytes, array &$chartData): void
76
    {
77
        $sessions = $this->sessionRepository->getSessionsByCourse($courseEntity);
78
79
        foreach ($sessions as $session) {
80
            $quotaBytes = $this->documentRepository->getTotalSpaceByCourse($courseEntity, null, $session);
81
82
            if ($quotaBytes > 0) {
83
                $sessionName = $session->getTitle();
84
                if ($sessionId === $session->getId()) {
85
                    $sessionName .= ' * ';
86
                }
87
88
                $usedQuotaBytes += $quotaBytes;
89
                $chartData[] = [
90
                    'label' => addslashes(get_lang('Session').': '.$sessionName).' ('.format_file_size($quotaBytes).')',
91
                    'percentage' => $this->calculatePercentage($quotaBytes, $totalQuotaBytes),
92
                ];
93
            }
94
        }
95
    }
96
97
    private function processCourseGroups($courseEntity, int $groupId, int $totalQuotaBytes, int &$usedQuotaBytes, array &$chartData): void
98
    {
99
        $groupsList = $this->groupRepository->findAllByCourse($courseEntity)->getQuery()->getResult();
100
101
        foreach ($groupsList as $groupEntity) {
102
            $quotaBytes = $this->documentRepository->getTotalSpaceByCourse($courseEntity, $groupEntity->getIid());
103
104
            if ($quotaBytes > 0) {
105
                $groupName = $groupEntity->getTitle();
106
                if ($groupId === $groupEntity->getIid()) {
107
                    $groupName .= ' * ';
108
                }
109
110
                $usedQuotaBytes += $quotaBytes;
111
                $chartData[] = [
112
                    'label' => addslashes(get_lang('Group').': '.$groupName).' ('.format_file_size($quotaBytes).')',
113
                    'percentage' => $this->calculatePercentage($quotaBytes, $totalQuotaBytes),
114
                ];
115
            }
116
        }
117
    }
118
119
    private function processUserDocuments($courseEntity, $sessionEntity, int $userId, string $userName, int $totalQuotaBytes, array &$chartData): void
120
    {
121
        $documentsList = $this->documentRepository->getAllDocumentDataByUserAndGroup($courseEntity);
122
        $userQuotaBytes = 0;
123
124
        foreach ($documentsList as $documentEntity) {
125
            if ($documentEntity->getResourceNode()->getCreator()?->getId() === $userId
126
                && 'file' === $documentEntity->getFiletype()) {
127
                $resourceFiles = $documentEntity->getResourceNode()->getResourceFiles();
128
                if (!$resourceFiles->isEmpty()) {
129
                    $userQuotaBytes += $resourceFiles->first()->getSize();
130
                }
131
            }
132
        }
133
134
        if ($userQuotaBytes > 0) {
135
            $chartData[] = [
136
                'label' => addslashes(get_lang('Teacher').': '.$userName).' ('.format_file_size($userQuotaBytes).')',
137
                'percentage' => $this->calculatePercentage($userQuotaBytes, $totalQuotaBytes),
138
            ];
139
140
            // Handle session context
141
            if ($sessionEntity) {
142
                $sessionTotalQuota = $this->calculateSessionTotalQuota($sessionEntity);
143
                if ($sessionTotalQuota > 0) {
144
                    $chartData[] = [
145
                        'label' => addslashes(\sprintf(get_lang('TeacherXInSession'), $userName)),
146
                        'percentage' => $this->calculatePercentage($userQuotaBytes, $sessionTotalQuota),
147
                    ];
148
                }
149
            }
150
        }
151
    }
152
153
    private function calculateSessionTotalQuota($sessionEntity): int
154
    {
155
        $total = 0;
156
        $sessionCourses = $sessionEntity->getCourses();
157
158
        foreach ($sessionCourses as $courseEntity) {
159
            $total += DocumentManager::get_course_quota($courseEntity->getId());
160
        }
161
162
        return $total;
163
    }
164
165
    private function calculatePercentage(int $bytes, int $totalBytes): float
166
    {
167
        if (0 === $totalBytes) {
168
            return 0.0;
169
        }
170
171
        return round(($bytes / $totalBytes) * 100, 2);
172
    }
173
}
174