Passed
Pull Request — master (#6896)
by
unknown
09:34
created

DocumentUsageAction::processCourseSessions()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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