From 23fe4a5b2e9ef7cac050774e727eee133e50fe52 Mon Sep 17 00:00:00 2001 From: Dave Adams <56132666+dave-the-tech-guy@users.noreply.github.com> Date: Sat, 31 Jan 2026 01:08:47 -0500 Subject: [PATCH 1/3] Refactor vCard generation #961 Refactor vCard generation to use a more concise approach for setting optional fields and addresses. This resolves an Apple vCard bug where HOME and WORK are erroneously consumed, even when no values are provided. --- app/Http/Controllers/UserController.php | 83 ++++++++++++++++++------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 3014d810..3c53da70 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -381,33 +381,67 @@ public function clickNumber(request $request) //Download Vcard public function vcard(request $request) { - $linkId = $request->id; - // Find the link with the specified ID - $link = Link::findOrFail($linkId); - - $json = $link->link; + $link = Link::findOrFail($request->id); // Decode the JSON to a PHP array - $data = json_decode($json, true); - + $data = json_decode($link->link, true) ?? []; + // Create a new vCard object $vcard = new VCard(); + + // Name: pass empty strings if missing + $vcard->addName( + $data['last_name'] ?? '', + $data['first_name'] ?? '', + $data['middle_name'] ?? '', + $data['prefix'] ?? '', + $data['suffix'] ?? '' + ); + + // Small helper: call $fn only if $value is meaningfully present + $runIf = function ($value, callable $fn) { + if (is_string($value)) $value = trim($value); + if ($value !== null && $value !== '') $fn($value); + }; + + // Optional fields - Only add if value is present + $runIf($data['organization'] ?? null, fn($v) => $vcard->addCompany($v)); + $runIf($data['vtitle'] ?? null, fn($v) => $vcard->addJobtitle($v)); + $runIf($data['role'] ?? null, fn($v) => $vcard->addRole($v)); + + $runIf($data['email'] ?? null, fn($v) => $vcard->addEmail($v)); + $runIf($data['work_email'] ?? null, fn($v) => $vcard->addEmail($v, 'Work')); + + $runIf($data['work_url'] ?? null, fn($v) => $vcard->addURL($v, 'Work')); + + $runIf($data['home_phone'] ?? null, fn($v) => $vcard->addPhoneNumber($v, 'HOME')); + $runIf($data['work_phone'] ?? null, fn($v) => $vcard->addPhoneNumber($v, 'WORK')); + $runIf($data['cell_phone'] ?? null, fn($v) => $vcard->addPhoneNumber($v, 'CELL')); + - // Set the vCard properties from the $data array - $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']); - $vcard->addCompany($data['organization']); - $vcard->addJobtitle($data['vtitle']); - $vcard->addRole($data['role']); - $vcard->addEmail($data['email']); - $vcard->addEmail($data['work_email'], 'WORK'); - $vcard->addURL($data['work_url'], 'WORK'); - $vcard->addPhoneNumber($data['home_phone'], 'HOME'); - $vcard->addPhoneNumber($data['work_phone'], 'WORK'); - $vcard->addPhoneNumber($data['cell_phone'], 'CELL'); - $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME'); - $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK'); - + // Addresses: add only if any component exists + $home = [ + $data['home_address_street'] ?? '', + $data['home_address_city'] ?? '', + $data['home_address_state'] ?? '', + $data['home_address_zip'] ?? '', + $data['home_address_country'] ?? '', + ]; + if (implode('', $home) !== '') { + $vcard->addAddress($home[0], '', $home[1], $home[2], $home[3], $home[4], 'HOME'); + } + + $work = [ + $data['work_address_street'] ?? '', + $data['work_address_city'] ?? '', + $data['work_address_state'] ?? '', + $data['work_address_zip'] ?? '', + $data['work_address_country'] ?? '', + ]; + if (implode('', $work) !== '') { + $vcard->addAddress($work[0], '', $work[1], $work[2], $work[3], $work[4], 'WORK'); + } // $vcard->addPhoto(base_path('img/1.png')); @@ -419,11 +453,12 @@ public function vcard(request $request) 'Content-Type' => 'text/x-vcard', 'Content-Disposition' => 'attachment; filename="contact.vcf"' ]; - + + // Increment our click count Link::where('id', $linkId)->increment('click_number', 1); // Return the file download response - return response()->make($file_contents, 200, $headers); + return response($file_contents, 200, $headers); } @@ -1129,4 +1164,4 @@ private function updateIcon($icon, $link) 'title' => $icon ]); } -} \ No newline at end of file +} From 9998f828d828753225987ecbcbee15db5ee7b07c Mon Sep 17 00:00:00 2001 From: Dave Adams <56132666+dave-the-tech-guy@users.noreply.github.com> Date: Sat, 31 Jan 2026 01:26:11 -0500 Subject: [PATCH 2/3] Misc cleanup Trim whitespace, restore $linkId usage to minimize changes --- app/Http/Controllers/UserController.php | 41 +++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 3c53da70..8821bfda 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -381,8 +381,10 @@ public function clickNumber(request $request) //Download Vcard public function vcard(request $request) { + $linkId = $request->id; + // Find the link with the specified ID - $link = Link::findOrFail($request->id); + $link = Link::findOrFail($linkId); // Decode the JSON to a PHP array $data = json_decode($link->link, true) ?? []; @@ -392,11 +394,11 @@ public function vcard(request $request) // Name: pass empty strings if missing $vcard->addName( - $data['last_name'] ?? '', - $data['first_name'] ?? '', - $data['middle_name'] ?? '', - $data['prefix'] ?? '', - $data['suffix'] ?? '' + trim((string)($data['last_name'] ?? '')), + trim((string)($data['first_name'] ?? '')), + trim((string)($data['middle_name'] ?? '')), + trim((string)($data['prefix'] ?? '')), + trim((string)($data['suffix'] ?? '')) ); // Small helper: call $fn only if $value is meaningfully present @@ -411,9 +413,9 @@ public function vcard(request $request) $runIf($data['role'] ?? null, fn($v) => $vcard->addRole($v)); $runIf($data['email'] ?? null, fn($v) => $vcard->addEmail($v)); - $runIf($data['work_email'] ?? null, fn($v) => $vcard->addEmail($v, 'Work')); + $runIf($data['work_email'] ?? null, fn($v) => $vcard->addEmail($v, 'WORK')); - $runIf($data['work_url'] ?? null, fn($v) => $vcard->addURL($v, 'Work')); + $runIf($data['work_url'] ?? null, fn($v) => $vcard->addURL($v, 'WORK')); $runIf($data['home_phone'] ?? null, fn($v) => $vcard->addPhoneNumber($v, 'HOME')); $runIf($data['work_phone'] ?? null, fn($v) => $vcard->addPhoneNumber($v, 'WORK')); @@ -422,22 +424,22 @@ public function vcard(request $request) // Addresses: add only if any component exists $home = [ - $data['home_address_street'] ?? '', - $data['home_address_city'] ?? '', - $data['home_address_state'] ?? '', - $data['home_address_zip'] ?? '', - $data['home_address_country'] ?? '', + trim((string)($data['home_address_street'] ?? '')), + trim((string)($data['home_address_city'] ?? '')), + trim((string)($data['home_address_state'] ?? '')), + trim((string)($data['home_address_zip'] ?? '')), + trim((string)($data['home_address_country'] ?? '')), ]; if (implode('', $home) !== '') { $vcard->addAddress($home[0], '', $home[1], $home[2], $home[3], $home[4], 'HOME'); } - + $work = [ - $data['work_address_street'] ?? '', - $data['work_address_city'] ?? '', - $data['work_address_state'] ?? '', - $data['work_address_zip'] ?? '', - $data['work_address_country'] ?? '', + trim((string)($data['work_address_street'] ?? '')), + trim((string)($data['work_address_city'] ?? '')), + trim((string)($data['work_address_state'] ?? '')), + trim((string)($data['work_address_zip'] ?? '')), + trim((string)($data['work_address_country'] ?? '')), ]; if (implode('', $work) !== '') { $vcard->addAddress($work[0], '', $work[1], $work[2], $work[3], $work[4], 'WORK'); @@ -454,7 +456,6 @@ public function vcard(request $request) 'Content-Disposition' => 'attachment; filename="contact.vcf"' ]; - // Increment our click count Link::where('id', $linkId)->increment('click_number', 1); // Return the file download response From fd89796a91333bf413fc70de7b129f0568eca18c Mon Sep 17 00:00:00 2001 From: Dave Adams <56132666+dave-the-tech-guy@users.noreply.github.com> Date: Sat, 31 Jan 2026 01:33:04 -0500 Subject: [PATCH 3/3] Minimize changes Revert unnecessary code style changes --- app/Http/Controllers/UserController.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 8821bfda..53dca7a3 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -386,9 +386,11 @@ public function vcard(request $request) // Find the link with the specified ID $link = Link::findOrFail($linkId); - // Decode the JSON to a PHP array - $data = json_decode($link->link, true) ?? []; + $json = $link->link; + // Decode the JSON to a PHP array + $data = json_decode($json, true); + // Create a new vCard object $vcard = new VCard(); @@ -459,7 +461,7 @@ public function vcard(request $request) Link::where('id', $linkId)->increment('click_number', 1); // Return the file download response - return response($file_contents, 200, $headers); + return response()->make($file_contents, 200, $headers); }