fix gitlab tests

This commit is contained in:
root
2026-06-09 02:32:58 -04:00
parent 20a0b6c4e5
commit 6def9993da
1489 changed files with 10449 additions and 11356 deletions
+62 -61
View File
@@ -33,13 +33,14 @@ class BadgePdfService
protected BadgeUserLookupService $userLookupService,
protected BadgePrintLogService $printLogService,
protected BadgeTextFormatter $formatter,
) {}
) {
}
/**
* Letter landscape PDF, 8 badges per page — students and/or staff (FPDF + QR PNG).
*
* @param int[] $studentIds Primary keys on `students.id`
* @param int[] $userIds Staff/admin/teacher keys on `users.id`
* @param int[] $userIds Staff/admin/teacher keys on `users.id`
*/
public function generate(
array $studentIds,
@@ -85,7 +86,7 @@ class BadgePdfService
try {
$qrPayload = (string) ($staffRow['user_id_for_qr'] ?? $staffRow['user_id'] ?? '');
if ($qrPayload === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $qrPayload)) {
if ($qrPayload === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $qrPayload)) {
$qrPayload = (string) (int) ($staffRow['user_id'] ?? 0);
}
@@ -143,7 +144,7 @@ class BadgePdfService
): string {
$html = $this->buildHtmlDocument($rows, $schoolName, $motto, $footerBlock);
$options = new Options;
$options = new Options();
$options->set('isHtml5ParserEnabled', true);
$options->set('isRemoteEnabled', true);
$options->set('defaultFont', 'DejaVu Sans');
@@ -167,7 +168,7 @@ class BadgePdfService
$this->tempQrFiles = [];
try {
if (! class_exists('FPDF', false)) {
if (!class_exists('FPDF', false)) {
require_once base_path('app/ThirdParty/fpdf/fpdf.php');
}
@@ -199,7 +200,7 @@ class BadgePdfService
for ($gridCol = 0; $gridCol < 4; $gridCol++) {
$idx = ($gridRow * 4) + $gridCol;
$row = $slots[$idx];
if (! is_array($row)) {
if (!is_array($row)) {
continue;
}
@@ -261,7 +262,7 @@ class BadgePdfService
array $classesMap
): ?array {
$info = $this->userLookupService->getUserInfoById($userId, $schoolYear);
if (! $info || ! is_array($info)) {
if (!$info || !is_array($info)) {
return null;
}
@@ -275,7 +276,7 @@ class BadgePdfService
$roleResolved = $this->formatter->formatRole($roleResolved);
$info['role_resolved'] = $roleResolved;
if (! empty($classesMap[$resolvedId])) {
if (!empty($classesMap[$resolvedId])) {
$info['class_section_name'] = (string) $classesMap[$resolvedId];
}
@@ -290,11 +291,11 @@ class BadgePdfService
if ($isTeacherish && $class !== '') {
if (strtolower($class) === 'youth') {
$display = 'Youth '.$roleResolved;
$display = 'Youth ' . $roleResolved;
} elseif ($class === 'KG') {
$display = 'KG '.$roleResolved;
$display = 'KG ' . $roleResolved;
} else {
$display = 'Grade '.$class.' '.$roleResolved;
$display = 'Grade ' . $class . ' ' . $roleResolved;
}
} elseif ($roleResolved !== '') {
$display = $roleResolved;
@@ -308,7 +309,7 @@ class BadgePdfService
$year = $this->formatter->norm((string) ($info['school_year'] ?? ($schoolYear ?? '')));
$schoolId = trim((string) ($info['school_id'] ?? ''));
if ($schoolId === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
if ($schoolId === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
return null;
}
@@ -363,10 +364,10 @@ class BadgePdfService
}
return '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Badges PDF</title><style>'
.$this->badgeCss()
.'</style></head><body>'
.$badgesHtml
.'</body></html>';
. $this->badgeCss()
. '</style></head><body>'
. $badgesHtml
. '</body></html>';
}
protected function buildBadgeHtml(
@@ -375,7 +376,8 @@ class BadgePdfService
string $motto,
string $footerBlock,
?string $logoDataUri
): string {
): string
{
$kind = (string) ($row['_badge_kind'] ?? 'student');
$idLabel = $kind === 'staff' ? 'User ID' : 'School ID';
$title = $this->escapeHtml((string) ($row['fullname'] ?? ''));
@@ -402,8 +404,8 @@ class BadgePdfService
<div class="info-row">
<span class="icon-badge">G</span>
<span class="info-copy">
<span class="label">'.$gradeLabel.'</span>
<span class="value">'.$grade.'</span>
<span class="label">' . $gradeLabel . '</span>
<span class="value">' . $grade . '</span>
</span>
</div>';
}
@@ -413,15 +415,15 @@ class BadgePdfService
<span class="icon-badge">Y</span>
<span class="info-copy">
<span class="label">Academic Year</span>
<span class="value">'.$year.'</span>
<span class="value">' . $year . '</span>
</span>
</div>
<div class="info-row">
<span class="icon-badge">ID</span>
<span class="info-copy">
<span class="label">'.$this->escapeHtml($idLabel).'</span>
<span class="value">'.$schoolId.'</span>
<span class="label">' . $this->escapeHtml($idLabel) . '</span>
<span class="value">' . $schoolId . '</span>
</span>
</div>';
@@ -430,18 +432,18 @@ class BadgePdfService
<div class="header-wrap">
<div class="header">
<div class="header-mark">'
.($logoDataUri !== null
? '<img src="'.$logoDataUri.'" alt="School Logo">'
: '<span>AS</span>').
. ($logoDataUri !== null
? '<img src="' . $logoDataUri . '" alt="School Logo">'
: '<span>AS</span>') .
'</div>
<div class="header-copy">
<div class="school-name">'.$this->escapeHtml($headerMainTitle).'</div>
'.($schoolLevel !== ''
? '<div class="sub-school">'.$this->escapeHtml($schoolLevel).'</div>'
: '').'
'.($headerMotto !== ''
? '<div class="motto">'.$this->escapeHtml($headerMotto).'</div>'
: '').'
<div class="school-name">' . $this->escapeHtml($headerMainTitle) . '</div>
' . ($schoolLevel !== ''
? '<div class="sub-school">' . $this->escapeHtml($schoolLevel) . '</div>'
: '') . '
' . ($headerMotto !== ''
? '<div class="motto">' . $this->escapeHtml($headerMotto) . '</div>'
: '') . '
</div>
</div>
<div class="header-accent"></div>
@@ -449,25 +451,25 @@ class BadgePdfService
</div>
<div class="body">
<div class="student-name">'.mb_strtoupper($title, 'UTF-8').'</div>
<div class="student-name">' . mb_strtoupper($title, 'UTF-8') . '</div>
<div class="name-divider">
<span class="divider-line"></span>
<span class="divider-dot"></span>
<span class="divider-line"></span>
</div>
<div class="role">'.mb_strtoupper($role, 'UTF-8').'</div>
<div class="role">' . mb_strtoupper($role, 'UTF-8') . '</div>
<table class="content">
<tr>
<td class="info">
'.$infoRows.'
' . $infoRows . '
</td>
<td class="qr-col">
<div class="qr-box">'
.($qrSrc !== ''
? '<img src="'.$qrSrc.'" alt="QR Code">'
: '').
. ($qrSrc !== ''
? '<img src="' . $qrSrc . '" alt="QR Code">'
: '') .
'</div>
<div class="scan-pill">Scan to verify</div>
</td>
@@ -475,18 +477,18 @@ class BadgePdfService
</table>
<div class="barcode-wrap">
<div class="barcode-bars">'.$this->buildBarcodeHtml($barcodeValue).'</div>
<div class="barcode-text">'.$barcodeText.'</div>
<div class="barcode-bars">' . $this->buildBarcodeHtml($barcodeValue) . '</div>
<div class="barcode-text">' . $barcodeText . '</div>
</div>
</div>
<div class="footer">
<span class="footer-mark">'
.($logoDataUri !== null
? '<img src="'.$logoDataUri.'" alt="School Logo">'
: '<span>S</span>').
. ($logoDataUri !== null
? '<img src="' . $logoDataUri . '" alt="School Logo">'
: '<span>S</span>') .
'</span>
<span class="footer-copy">'.$footer.'</span>
<span class="footer-copy">' . $footer . '</span>
</div>
</div>
';
@@ -897,7 +899,7 @@ CSS;
default => '4px',
};
$bars[] = '<span class="barcode-bar" style="width:'.$width.'"></span>';
$bars[] = '<span class="barcode-bar" style="width:' . $width . '"></span>';
$bars[] = '<span class="barcode-bar" style="width:1px"></span>';
}
@@ -915,7 +917,7 @@ CSS;
return null;
}
$tmpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'badge_qr_'.bin2hex(random_bytes(8)).'.png';
$tmpPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'badge_qr_' . bin2hex(random_bytes(8)) . '.png';
if (@file_put_contents($tmpPath, $png) === false) {
return null;
}
@@ -1000,11 +1002,11 @@ CSS;
{
return $this->formatter->firstExisting([
public_path($filename),
public_path('badges/'.$filename),
public_path('assets/images/'.$filename),
public_path('assets/images/badges/'.$filename),
storage_path('app/public/'.$filename),
storage_path('app/public/badges/'.$filename),
public_path('badges/' . $filename),
public_path('assets/images/' . $filename),
public_path('assets/images/badges/' . $filename),
storage_path('app/public/' . $filename),
storage_path('app/public/badges/' . $filename),
]);
}
@@ -1085,7 +1087,7 @@ CSS;
/**
* Shrink text until it fits in the available width. FPDF, bravely, does not do this for us.
*
* @param array{0:int,1:int,2:int} $rgb
* @param array{0:int,1:int,2:int} $rgb
*/
protected function fitCenteredText(
\FPDF $pdf,
@@ -1147,7 +1149,7 @@ CSS;
}
/**
* @param array{0:int,1:int,2:int} $rgb
* @param array{0:int,1:int,2:int} $rgb
*/
protected function fitLeftText(
\FPDF $pdf,
@@ -1445,7 +1447,6 @@ CSS;
foreach ($segments as [$type, $segmentWidth]) {
if ($type === 'gap') {
$cursor += $segmentWidth;
continue;
}
@@ -1509,7 +1510,7 @@ CSS;
protected function preparedLogoPath(): ?string
{
$path = $this->logoFilePath();
if ($path === null || ! is_readable($path)) {
if ($path === null || !is_readable($path)) {
return null;
}
@@ -1518,7 +1519,7 @@ CSS;
return $path;
}
$tmpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'badge_logo_'.bin2hex(random_bytes(8)).'.png';
$tmpPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'badge_logo_' . bin2hex(random_bytes(8)) . '.png';
if (@file_put_contents($tmpPath, $png) === false) {
return $path;
}
@@ -1531,7 +1532,7 @@ CSS;
protected function logoDataUri(): ?string
{
$path = $this->logoFilePath();
if ($path === null || ! is_readable($path)) {
if ($path === null || !is_readable($path)) {
return null;
}
@@ -1543,9 +1544,10 @@ CSS;
return null;
}
return 'data:image/png;base64,'.base64_encode($bytes);
return 'data:image/png;base64,' . base64_encode($bytes);
}
protected function headerMainTitle(string $schoolName): string
{
$name = trim($schoolName) !== '' ? trim($schoolName) : 'Al Rahma Sunday School';
@@ -1577,7 +1579,7 @@ CSS;
{
$address = trim((string) config('badges.footer_address', ''));
if ($address !== '') {
return $schoolName."\n".$address;
return $schoolName . "\n" . $address;
}
return $schoolName;
@@ -1585,7 +1587,7 @@ CSS;
protected function makeCircularPngBytesFromPath(string $path): ?string
{
if (! function_exists('imagecreatetruecolor') || ! function_exists('imagepng')) {
if (!function_exists('imagecreatetruecolor') || !function_exists('imagepng')) {
return null;
}
@@ -1624,7 +1626,6 @@ CSS;
$circle = imagecreatetruecolor($size, $size);
if ($circle === false) {
imagedestroy($square);
return null;
}