prepareViewData($user))->render(); return $this->makeBrowsershot($html)->screenshot(); } /** * @return array */ protected function prepareViewData(User $user): array { $user = app(PublicMemberProfileService::class)->loadVerifiableRelations($user); $user->ensurePublicProfileToken(); $currentEmployment = $user->employments->firstWhere('is_current', true) ?? $user->employments->first(); $logoPath = config('user.digital_card_logo_path'); $profileUrl = rtrim(config('user.frontend_url'), '/').'/v/'.$user->public_profile_token; return [ 'memberNumber' => $this->displayCardValue($user->member_number), 'memberName' => $user->name ?: '-', 'memberType' => $this->displayCardValue($user->member_type), 'companyName' => $this->displayCardValue($currentEmployment?->company_name), 'avatarDataUri' => $this->resolveStorageDataUri($user->image_url), 'avatarInitials' => $this->avatarInitials($user->name), 'logoDataUri' => $this->resolveFileDataUri($logoPath), 'profileUrl' => $profileUrl, 'qrDataUri' => $this->generateQrDataUri($profileUrl), ]; } protected function makeBrowsershot(string $html): Browsershot { $browsershot = Browsershot::html($html) ->setNodeModulePath(config('browsershot.node_module_path')) ->timeout(config('browsershot.timeout')) ->windowSize(self::CARD_WIDTH, self::CARD_HEIGHT) ->deviceScaleFactor(2) ->showBackground(); if ($nodeBinary = config('browsershot.node_binary')) { $browsershot->setNodeBinary($nodeBinary); } if ($npmBinary = config('browsershot.npm_binary')) { $browsershot->setNpmBinary($npmBinary); } if ($chromePath = config('browsershot.chrome_path')) { $browsershot->setChromePath($chromePath); } if (config('browsershot.no_sandbox')) { $browsershot->noSandbox(); } return $browsershot; } protected function generateQrDataUri(string $content): string { $renderer = new ImageRenderer( new RendererStyle(220, 1), new SvgImageBackEnd ); $writer = new Writer($renderer); $svg = $writer->writeString($content); return 'data:image/svg+xml;base64,'.base64_encode($svg); } protected function resolveFileDataUri(?string $path): ?string { if (empty($path) || ! file_exists($path)) { return null; } $mime = mime_content_type($path) ?: 'image/svg+xml'; return 'data:'.$mime.';base64,'.base64_encode(file_get_contents($path)); } protected function resolveStorageDataUri(?string $path): ?string { if (blank($path)) { return null; } $fullPath = Storage::disk('public')->path($path); return $this->resolveFileDataUri($fullPath); } protected function avatarInitials(?string $name): string { $trimmed = trim((string) $name); if ($trimmed === '') { return '--'; } return strtoupper(mb_substr($trimmed, 0, 2)); } protected function displayCardValue(mixed $value): string { if ($value === null || $value === '') { return '-'; } $trimmed = trim((string) $value); return $trimmed !== '' ? $trimmed : '-'; } }