fix certificate qr
This commit is contained in:
@@ -77,6 +77,17 @@ class CertificateController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
public function csrfToken()
|
||||
{
|
||||
return $this->response
|
||||
->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->setHeader('Pragma', 'no-cache')
|
||||
->setJSON([
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
|
||||
// ─── Public verification page ──────────────────────────────────────────────
|
||||
|
||||
public function verify(string $certNumber)
|
||||
@@ -101,6 +112,16 @@ class CertificateController extends BaseController
|
||||
$schoolYear = $this->request->getPost('school_year') ?? $this->schoolYear;
|
||||
|
||||
if (empty($studentIds)) {
|
||||
if ($this->request->isAJAX()) {
|
||||
return $this->response
|
||||
->setStatusCode(422)
|
||||
->setJSON([
|
||||
'ok' => false,
|
||||
'error' => 'Please select at least one student.',
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
return redirect()->to('administrator/certificates')->with('error', 'Please select at least one student.');
|
||||
}
|
||||
|
||||
@@ -108,6 +129,16 @@ class CertificateController extends BaseController
|
||||
$certDate = preg_replace('/[^0-9\/\-]/', '', $certDate);
|
||||
|
||||
if (empty($studentIds)) {
|
||||
if ($this->request->isAJAX()) {
|
||||
return $this->response
|
||||
->setStatusCode(422)
|
||||
->setJSON([
|
||||
'ok' => false,
|
||||
'error' => 'Invalid student selection.',
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
return redirect()->to('administrator/certificates')->with('error', 'Invalid student selection.');
|
||||
}
|
||||
|
||||
@@ -140,6 +171,16 @@ class CertificateController extends BaseController
|
||||
}
|
||||
|
||||
if (empty($students)) {
|
||||
if ($this->request->isAJAX()) {
|
||||
return $this->response
|
||||
->setStatusCode(422)
|
||||
->setJSON([
|
||||
'ok' => false,
|
||||
'error' => 'No valid students found.',
|
||||
'csrf_token' => csrf_token(),
|
||||
'csrf_hash' => csrf_hash(),
|
||||
]);
|
||||
}
|
||||
return redirect()->to('administrator/certificates')->with('error', 'No valid students found.');
|
||||
}
|
||||
|
||||
@@ -170,6 +211,8 @@ class CertificateController extends BaseController
|
||||
return $this->response
|
||||
->setHeader('Content-Type', 'application/pdf')
|
||||
->setHeader('Content-Disposition', 'inline; filename="' . $filename . '"')
|
||||
->setHeader('X-CSRF-TOKEN-NAME', csrf_token())
|
||||
->setHeader('X-CSRF-TOKEN', csrf_hash())
|
||||
->setBody($pdfData);
|
||||
}
|
||||
|
||||
@@ -204,30 +247,6 @@ class CertificateController extends BaseController
|
||||
return $clean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a QR code PNG for $url and returns its temporary file path.
|
||||
* Caller must unlink() the file when done.
|
||||
*/
|
||||
private function makeQrTempFile(string $url): ?string
|
||||
{
|
||||
try {
|
||||
$result = \Endroid\QrCode\Builder\Builder::create()
|
||||
->writer(new \Endroid\QrCode\Writer\PngWriter())
|
||||
->data($url)
|
||||
->encoding(new \Endroid\QrCode\Encoding\Encoding('UTF-8'))
|
||||
->size(300)
|
||||
->margin(2)
|
||||
->build();
|
||||
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'cert_qr_') . '.png';
|
||||
$result->saveToFile($tmp);
|
||||
return $tmp;
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Certificate QR generation failed: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── PDF rendering ─────────────────────────────────────────────────────────
|
||||
|
||||
private function buildPdf(array $students, string $certDate): string
|
||||
@@ -252,8 +271,6 @@ class CertificateController extends BaseController
|
||||
$W = $pdf->getPageWidth();
|
||||
$H = $pdf->getPageHeight();
|
||||
|
||||
$tmpFiles = [];
|
||||
|
||||
foreach ($students as $student) {
|
||||
$pdf->AddPage();
|
||||
|
||||
@@ -261,28 +278,18 @@ class CertificateController extends BaseController
|
||||
$grade = $this->formatGrade($student['grade'] ?? '');
|
||||
$certNumber = $student['cert_number'] ?? '';
|
||||
|
||||
// Build verification URL and generate QR temp file
|
||||
$verifyUrl = base_url('verify/' . rawurlencode($certNumber));
|
||||
$qrFile = $certNumber !== '' ? $this->makeQrTempFile($verifyUrl) : null;
|
||||
if ($qrFile) {
|
||||
$tmpFiles[] = $qrFile;
|
||||
}
|
||||
// Build verification URL for an inline TCPDF QR code.
|
||||
$verifyUrl = site_url('verify/' . rawurlencode($certNumber));
|
||||
|
||||
$this->drawCertificate(
|
||||
$pdf, $W, $H,
|
||||
$name, $grade, $certDate, $certNumber,
|
||||
$qrFile,
|
||||
$verifyUrl,
|
||||
$imgDir, $edwardianFont, $garamondBold, $ebGaramond
|
||||
);
|
||||
}
|
||||
|
||||
$output = $pdf->Output('', 'S');
|
||||
|
||||
foreach ($tmpFiles as $f) {
|
||||
@unlink($f);
|
||||
}
|
||||
|
||||
return $output;
|
||||
return $pdf->Output('', 'S');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,7 +304,7 @@ class CertificateController extends BaseController
|
||||
string $grade,
|
||||
string $certDate,
|
||||
string $certNumber,
|
||||
?string $qrFile,
|
||||
?string $verifyUrl,
|
||||
string $imgDir,
|
||||
string $edwardianFont,
|
||||
string $garamondBold,
|
||||
@@ -310,10 +317,16 @@ class CertificateController extends BaseController
|
||||
|
||||
// ── QR code — bottom-right corner: 1.5 cm from bottom, 2.5 cm from right
|
||||
$qrSize = 42; // pt
|
||||
if ($qrFile !== null && file_exists($qrFile)) {
|
||||
if (!empty($verifyUrl)) {
|
||||
$qrX = $W - 70.87 - $qrSize; // 2.5 cm from right edge
|
||||
$qrY = $H - 42.52 - $qrSize; // 1.5 cm from bottom edge
|
||||
$pdf->Image($qrFile, $qrX, $qrY, $qrSize, $qrSize);
|
||||
$style = [
|
||||
'border' => false,
|
||||
'padding' => 0,
|
||||
'fgcolor' => [0, 0, 0],
|
||||
'bgcolor' => false,
|
||||
];
|
||||
$pdf->write2DBarcode($verifyUrl, 'QRCODE,L', $qrX, $qrY, $qrSize, $qrSize, $style, 'N');
|
||||
}
|
||||
|
||||
// ── "Presented to:"
|
||||
|
||||
Reference in New Issue
Block a user