137 lines
4.3 KiB
PHP
137 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services\ClassProgress;
|
|
|
|
class ClassProgressRuleService
|
|
{
|
|
/** legacy `ClassProgressController::CUSTOM_UNIT_ROW_LABEL` — must match teacher form JS. */
|
|
public const CUSTOM_UNIT_ROW_LABEL = 'Custom';
|
|
|
|
public function defaultStatus(): string
|
|
{
|
|
return 'on_track';
|
|
}
|
|
|
|
public function normalizeFlags($flags): ?array
|
|
{
|
|
$values = array_values(array_filter((array) $flags, static fn ($item) => $item !== '' && $item !== null));
|
|
return $values === [] ? null : $values;
|
|
}
|
|
|
|
/**
|
|
* legacy `buildUnitChapterSummary` — Custom / typed chapter rows preserved.
|
|
*
|
|
* @param array<int|string, mixed> $unitValues
|
|
* @param array<int|string, mixed> $chapterValues
|
|
*/
|
|
public function buildUnitChapterSummary(array $unitValues, array $chapterValues): ?string
|
|
{
|
|
$parts = [];
|
|
$count = max(count($unitValues), count($chapterValues));
|
|
for ($i = 0; $i < $count; $i++) {
|
|
$unit = trim((string) ($unitValues[$i] ?? ''));
|
|
$chapter = trim((string) ($chapterValues[$i] ?? ''));
|
|
if ($unit === '' && $chapter === '') {
|
|
continue;
|
|
}
|
|
if (strcasecmp($unit, self::CUSTOM_UNIT_ROW_LABEL) === 0 && $chapter !== '') {
|
|
$unit = self::CUSTOM_UNIT_ROW_LABEL;
|
|
}
|
|
$segment = $unit;
|
|
if ($chapter !== '') {
|
|
$segment = $segment !== '' ? $unit.' / '.$chapter : $chapter;
|
|
}
|
|
if ($segment === '') {
|
|
continue;
|
|
}
|
|
$parts[] = $segment;
|
|
}
|
|
|
|
if ($parts === []) {
|
|
return null;
|
|
}
|
|
|
|
$summary = implode(' ; ', $parts);
|
|
|
|
return mb_strlen($summary) > 120 ? mb_substr($summary, 0, 120) : $summary;
|
|
}
|
|
|
|
/** legacy `hasIslamicUnitSelection`. */
|
|
public function hasIslamicUnitSelection(array $payload): bool
|
|
{
|
|
$unitValues = array_map('trim', (array) ($payload['unit_islamic'] ?? []));
|
|
$chapterValues = array_map('trim', (array) ($payload['chapter_islamic'] ?? []));
|
|
$count = max(count($unitValues), count($chapterValues));
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if (($unitValues[$i] ?? '') !== '' || ($chapterValues[$i] ?? '') !== '') {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function ensureWeekEnd(string $weekStart, ?string $weekEnd): string
|
|
{
|
|
if ($weekEnd) {
|
|
return $weekEnd;
|
|
}
|
|
|
|
try {
|
|
$dt = new \DateTime($weekStart);
|
|
$dt->modify('+6 days');
|
|
return $dt->format('Y-m-d');
|
|
} catch (\Exception $e) {
|
|
return $weekStart;
|
|
}
|
|
}
|
|
|
|
public function isWeekEndValid(string $weekStart, string $weekEnd): bool
|
|
{
|
|
return strtotime($weekEnd) >= strtotime($weekStart);
|
|
}
|
|
|
|
/**
|
|
* legacy `parseUnitChapterSummary` — inverse of {@see buildUnitChapterSummary()} for edit forms.
|
|
*
|
|
* @return array{units: list<string>, chapters: list<string>}
|
|
*/
|
|
public function parseUnitChapterSummary(string $summary): array
|
|
{
|
|
$summary = trim($summary);
|
|
if ($summary === '') {
|
|
return ['units' => [], 'chapters' => []];
|
|
}
|
|
|
|
$units = [];
|
|
$chapters = [];
|
|
$segments = preg_split('/\s*;\s*/', $summary, -1, PREG_SPLIT_NO_EMPTY);
|
|
foreach ($segments as $segment) {
|
|
$segment = trim((string) $segment);
|
|
if ($segment === '') {
|
|
continue;
|
|
}
|
|
if (preg_match('/^Custom\s*\/\s*(.+)$/iu', $segment, $m)) {
|
|
$units[] = self::CUSTOM_UNIT_ROW_LABEL;
|
|
$chapters[] = trim($m[1]);
|
|
|
|
continue;
|
|
}
|
|
$parts = preg_split('/\s*\/\s*/', $segment, 2);
|
|
if (count($parts) === 2) {
|
|
$u = trim($parts[0]);
|
|
if (strcasecmp($u, self::CUSTOM_UNIT_ROW_LABEL) === 0) {
|
|
$u = self::CUSTOM_UNIT_ROW_LABEL;
|
|
}
|
|
$units[] = $u;
|
|
$chapters[] = trim($parts[1]);
|
|
} else {
|
|
$units[] = $segment;
|
|
$chapters[] = '';
|
|
}
|
|
}
|
|
|
|
return ['units' => $units, 'chapters' => $chapters];
|
|
}
|
|
}
|