fix class progress unit numbers calculation

This commit is contained in:
root
2026-03-31 00:16:55 -04:00
parent d2abbc1458
commit ed67836701
2 changed files with 85 additions and 39 deletions
+84 -38
View File
@@ -432,13 +432,11 @@ class AdminProgressController extends BaseController
$allowedSubjects = array_values(array_filter($allowedSubjects)); $allowedSubjects = array_values(array_filter($allowedSubjects));
$counts = []; $counts = [];
$latestWeekBySection = [];
$sectionClassMap = []; $sectionClassMap = [];
foreach ($rows as $row) { foreach ($rows as $row) {
$sectionId = (int) ($row['class_section_id'] ?? 0); $sectionId = (int) ($row['class_section_id'] ?? 0);
$subject = (string) ($row['subject'] ?? ''); $subject = (string) ($row['subject'] ?? '');
$weekStart = (string) ($row['week_start'] ?? ''); if ($sectionId === 0 || $subject === '') {
if ($sectionId === 0 || $subject === '' || $weekStart === '') {
continue; continue;
} }
if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) { if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) {
@@ -447,45 +445,41 @@ class AdminProgressController extends BaseController
if (! isset($sectionClassMap[$sectionId])) { if (! isset($sectionClassMap[$sectionId])) {
$sectionClassMap[$sectionId] = $this->classSectionModel->getClassId($sectionId); $sectionClassMap[$sectionId] = $this->classSectionModel->getClassId($sectionId);
} }
if (
! isset($latestWeekBySection[$sectionId])
|| $weekStart > $latestWeekBySection[$sectionId]
) {
$latestWeekBySection[$sectionId] = $weekStart;
}
} }
$curriculumChapters = $this->buildCurriculumChapterMap(array_values(array_filter($sectionClassMap))); $curriculumUnits = $this->buildCurriculumUnitMap(array_values(array_filter($sectionClassMap)));
foreach ($rows as $row) { foreach ($rows as $row) {
$sectionId = (int) ($row['class_section_id'] ?? 0); $sectionId = (int) ($row['class_section_id'] ?? 0);
$subject = (string) ($row['subject'] ?? ''); $subject = (string) ($row['subject'] ?? '');
$weekStart = (string) ($row['week_start'] ?? ''); if ($sectionId === 0 || $subject === '') {
if ($sectionId === 0 || $subject === '' || $weekStart === '') {
continue; continue;
} }
if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) { if (! empty($allowedSubjects) && ! in_array($subject, $allowedSubjects, true)) {
continue; continue;
} }
if (empty($latestWeekBySection[$sectionId]) || $weekStart !== $latestWeekBySection[$sectionId]) {
continue;
}
$subjectSlug = $this->resolveSubjectSlug($subject); $subjectSlug = $this->resolveSubjectSlug($subject);
$classId = $sectionClassMap[$sectionId] ?? null; $classId = $sectionClassMap[$sectionId] ?? null;
$chapterSet = []; $chapterToUnit = [];
if ($classId && $subjectSlug && ! empty($curriculumChapters[$classId][$subjectSlug])) { if ($classId && $subjectSlug && ! empty($curriculumUnits[$classId][$subjectSlug]['chapter_to_unit'])) {
$chapterSet = $curriculumChapters[$classId][$subjectSlug]; $chapterToUnit = $curriculumUnits[$classId][$subjectSlug]['chapter_to_unit'];
}
$unitKeys = $this->extractUnitKeys((string) ($row['unit_title'] ?? ''), $chapterToUnit);
foreach ($unitKeys as $unitKey) {
$key = $subjectSlug . '|' . $unitKey;
$counts[$sectionId][$key] = true;
} }
$counts[$sectionId] = ($counts[$sectionId] ?? 0) + $this->countChapterSegments(
(string) ($row['unit_title'] ?? ''),
$chapterSet
);
} }
return $counts; $totals = [];
foreach ($counts as $sectionId => $unitSet) {
$totals[$sectionId] = count($unitSet);
} }
protected function buildCurriculumChapterMap(array $classIds): array return $totals;
}
protected function buildCurriculumUnitMap(array $classIds): array
{ {
$classIds = array_values(array_filter(array_map('intval', $classIds))); $classIds = array_values(array_filter(array_map('intval', $classIds)));
if (empty($classIds)) { if (empty($classIds)) {
@@ -501,10 +495,15 @@ class AdminProgressController extends BaseController
$classId = (int) ($row['class_id'] ?? 0); $classId = (int) ($row['class_id'] ?? 0);
$subject = (string) ($row['subject'] ?? ''); $subject = (string) ($row['subject'] ?? '');
$chapter = trim((string) ($row['chapter_name'] ?? '')); $chapter = trim((string) ($row['chapter_name'] ?? ''));
$unitNumber = $row['unit_number'] ?? null;
if ($classId === 0 || $subject === '' || $chapter === '') { if ($classId === 0 || $subject === '' || $chapter === '') {
continue; continue;
} }
$map[$classId][$subject][$chapter] = true; if ($unitNumber === null || $unitNumber === '') {
continue;
}
$unitKey = (string) $unitNumber;
$map[$classId][$subject]['chapter_to_unit'][$chapter] = $unitKey;
} }
return $map; return $map;
@@ -522,46 +521,93 @@ class AdminProgressController extends BaseController
return null; return null;
} }
protected function countChapterSegments(string $unitTitle, array $chapterSet): int protected function countUnitSegments(string $unitTitle, array $chapterToUnit): int
{ {
$unitTitle = trim($unitTitle); $unitTitle = trim($unitTitle);
if ($unitTitle === '') { if ($unitTitle === '') {
return 1; return 0;
} }
$parts = array_filter(array_map('trim', explode(';', $unitTitle)), static fn ($part) => $part !== ''); $parts = array_filter(array_map('trim', explode(';', $unitTitle)), static fn ($part) => $part !== '');
if (! $parts) { if (! $parts) {
return 1; return 0;
} }
$count = 0;
$seen = []; $seen = [];
foreach ($parts as $part) { foreach ($parts as $part) {
$chapter = $this->extractChapterFromSegment($part); [$unitPart, $chapterPart] = $this->splitUnitChapterSegment($part);
$key = $chapter !== '' ? $chapter : $part; $key = $this->resolveUnitKey($unitPart, $chapterPart, $chapterToUnit);
if (! empty($chapterSet) && $chapter !== '' && empty($chapterSet[$chapter])) { if ($key === '') {
$key = $part; $key = $part;
} }
if (isset($seen[$key])) { if (isset($seen[$key])) {
continue; continue;
} }
$seen[$key] = true; $seen[$key] = true;
$count++;
} }
return $count > 0 ? $count : 1; return count($seen);
} }
protected function extractChapterFromSegment(string $segment): string protected function splitUnitChapterSegment(string $segment): array
{ {
$segment = trim($segment); $segment = trim($segment);
if ($segment === '') { if ($segment === '') {
return ''; return ['', ''];
} }
$pos = strrpos($segment, '/'); $pos = strrpos($segment, '/');
if ($pos === false) { if ($pos === false) {
return $segment; return [$segment, ''];
} }
return trim(substr($segment, $pos + 1)); $unitPart = trim(substr($segment, 0, $pos));
$chapterPart = trim(substr($segment, $pos + 1));
return [$unitPart, $chapterPart];
}
protected function extractUnitKeys(string $unitTitle, array $chapterToUnit): array
{
$unitTitle = trim($unitTitle);
if ($unitTitle === '') {
return [];
}
$parts = array_filter(array_map('trim', explode(';', $unitTitle)), static fn ($part) => $part !== '');
if (! $parts) {
return [];
}
$keys = [];
foreach ($parts as $part) {
[$unitPart, $chapterPart] = $this->splitUnitChapterSegment($part);
$key = $this->resolveUnitKey($unitPart, $chapterPart, $chapterToUnit);
if ($key === '') {
continue;
}
$keys[$key] = true;
}
return array_keys($keys);
}
protected function resolveUnitKey(string $unitPart, string $chapterPart, array $chapterToUnit): string
{
if ($chapterPart !== '' && ! empty($chapterToUnit[$chapterPart])) {
return (string) $chapterToUnit[$chapterPart];
}
if (empty($chapterToUnit)) {
if (preg_match('/\bunit\s*(\d+)\b/i', $unitPart, $matches)) {
return (string) $matches[1];
}
return '';
}
if (preg_match('/\bunit\s*(\d+)\b/i', $unitPart, $matches)) {
return (string) $matches[1];
}
if ($unitPart !== '') {
return $unitPart;
}
if ($chapterPart !== '') {
return $chapterPart;
}
return '';
} }
protected function buildSectionStat(int $submitted, int $expectedDays): array protected function buildSectionStat(int $submitted, int $expectedDays): array
+1 -1
View File
@@ -132,7 +132,7 @@
$submissionLabel = $expectedDays > 0 $submissionLabel = $expectedDays > 0
? ('Submitted: ' . (int) $stat['submitted'] . ' / ' . (int) $expectedDays . ' (' . $percentLabel . ')') ? ('Submitted: ' . (int) $stat['submitted'] . ' / ' . (int) $expectedDays . ' (' . $percentLabel . ')')
: 'Submitted: N/A'; : 'Submitted: N/A';
$subjectLabel = 'Subjects: ' . $subjectCount; $subjectLabel = 'Units: ' . $subjectCount;
?> ?>
<div class="accordion-item mb-2"> <div class="accordion-item mb-2">
<h2 class="accordion-header" id="<?= esc($headingId) ?>"> <h2 class="accordion-header" id="<?= esc($headingId) ?>">