Initial Vcard

Added Vcard feature
This commit is contained in:
Julian Prieber 2023-03-27 19:04:41 +02:00
parent 948b0b61b9
commit adee9ccaec
12 changed files with 1991 additions and 1036 deletions

View File

@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Hash;
use Cohensive\OEmbed\Facades\OEmbed;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Route;
use JeroenDesloovere\VCard\VCard;
use Auth;
use DB;
@ -144,6 +145,8 @@ class UserController extends Controller
$data['linkTypeID'] = "6";
} elseif ($bid == 44) {
$data['linkTypeID'] = "7";
} elseif ($bid == 96) {
$data['linkTypeID'] = "8";
} else {
$data['linkTypeID'] = "1";
}
@ -245,6 +248,69 @@ class UserController extends Controller
'button_id' => $button?->id,
'title' => $LinkTitle,
]);
}elseif($linkType->typename == "vcard"){
$prefix = $request->input('prefix');
$firstName = $request->input('first_name');
$middleName = $request->input('middle_name');
$lastName = $request->input('last_name');
$suffix = $request->input('suffix');
$nickname = $request->input('nickname');
$organization = $request->input('organization');
$title = $request->input('title');
$role = $request->input('role');
$workUrl = $request->input('work_url');
$email = $request->input('email');
$workEmail = $request->input('work_email');
$homePhone = $request->input('home_phone');
$workPhone = $request->input('work_phone');
$cellPhone = $request->input('cell_phone');
$homeAddressLabel = $request->input('home_address_label');
$homeAddressStreet = $request->input('home_address_street');
$homeAddressCity = $request->input('home_address_city');
$homeAddressState = $request->input('home_address_state');
$homeAddressZip = $request->input('home_address_zip');
$homeAddressCountry = $request->input('home_address_country');
$workAddressLabel = $request->input('work_address_label');
$workAddressStreet = $request->input('work_address_street');
$workAddressCity = $request->input('work_address_city');
$workAddressState = $request->input('work_address_state');
$workAddressZip = $request->input('work_address_zip');
$workAddressCountry = $request->input('work_address_country');
// Create a new vCard instance
$vCard = new VCard();
// Set the personal information
$vCard->addName($lastName, $firstName, $middleName, $prefix, $suffix);
$vCard->addRole($role);
// Set the organization information
$vCard->addCompany($organization);
$vCard->addJobtitle($title);
$vCard->addUrl($workUrl);
// Set the phone numbers
$vCard->addPhoneNumber($homePhone, 'HOME');
$vCard->addPhoneNumber($workPhone, 'WORK');
$vCard->addPhoneNumber($cellPhone, 'CELL');
// Set the email addresses
$vCard->addEmail($email, 'HOME');
$vCard->addEmail($workEmail, 'WORK');
// Set the addresses
$vCard->addAddress($homeAddressStreet, null, null, $homeAddressCity, $homeAddressState, $homeAddressZip, $homeAddressCountry, 'HOME', $homeAddressLabel);
$vCard->addAddress($workAddressStreet, null, null, $workAddressCity, $workAddressState, $workAddressZip, $workAddressCountry, 'WORK', $workAddressLabel);
// Generate the vCard file content
$LinkURL = $vCard->getOutput();
$OrigLink->update([
'link' => $LinkURL,
'button_id' => 96,
'title' => $LinkTitle,
]);
}else{
$OrigLink->update([
'link' => $LinkURL,
@ -286,6 +352,65 @@ class UserController extends Controller
}elseif($linkType->typename == "telephone"){
$links->link = "tel:".$links->link;
$links->button_id = $button?->id;
}elseif($linkType->typename == "vcard"){
$prefix = $request->input('prefix');
$firstName = $request->input('first_name');
$middleName = $request->input('middle_name');
$lastName = $request->input('last_name');
$suffix = $request->input('suffix');
$nickname = $request->input('nickname');
$organization = $request->input('organization');
$title = $request->input('title');
$role = $request->input('role');
$workUrl = $request->input('work_url');
$email = $request->input('email');
$workEmail = $request->input('work_email');
$homePhone = $request->input('home_phone');
$workPhone = $request->input('work_phone');
$cellPhone = $request->input('cell_phone');
$homeAddressLabel = $request->input('home_address_label');
$homeAddressStreet = $request->input('home_address_street');
$homeAddressCity = $request->input('home_address_city');
$homeAddressState = $request->input('home_address_state');
$homeAddressZip = $request->input('home_address_zip');
$homeAddressCountry = $request->input('home_address_country');
$workAddressLabel = $request->input('work_address_label');
$workAddressStreet = $request->input('work_address_street');
$workAddressCity = $request->input('work_address_city');
$workAddressState = $request->input('work_address_state');
$workAddressZip = $request->input('work_address_zip');
$workAddressCountry = $request->input('work_address_country');
// Create a new vCard instance
$vCard = new VCard();
// Set the personal information
$vCard->addName($lastName, $firstName, $middleName, $prefix, $suffix);
$vCard->addRole($role);
// Set the organization information
$vCard->addCompany($organization);
$vCard->addJobtitle($title);
$vCard->addUrl($workUrl);
// Set the phone numbers
$vCard->addPhoneNumber($homePhone, 'HOME');
$vCard->addPhoneNumber($workPhone, 'WORK');
$vCard->addPhoneNumber($cellPhone, 'CELL');
// Set the email addresses
$vCard->addEmail($email, 'HOME');
$vCard->addEmail($workEmail, 'WORK');
// Set the addresses
$vCard->addAddress($homeAddressStreet, null, null, $homeAddressCity, $homeAddressState, $homeAddressZip, $homeAddressCountry, 'HOME', $homeAddressLabel);
$vCard->addAddress($workAddressStreet, null, null, $workAddressCity, $workAddressState, $workAddressZip, $workAddressCountry, 'WORK', $workAddressLabel);
// Generate the vCard file content
$links->link = $vCard->getOutput();
$links->button_id = 96;
}else{
$links->button_id = $button?->id;
}
@ -353,6 +478,28 @@ class UserController extends Controller
return redirect()->away($link);
}
//Download Vcard
public function vcard(Request $request)
{
$linkId = $request->id;
$link = Link::findOrFail($linkId); // find the link with the given ID or throw an exception
$buttonValue = $link->button_value;
$content = $link->content;
Link::where('id', $linkId)->increment('click_number', 1);
// build the vCard string
$vCard = "BEGIN:VCARD\r\nVERSION:3.0\r\n";
$vCard .= "FN:$buttonValue\r\n";
$vCard .= "NOTE:$content\r\n";
$vCard .= "END:VCARD\r\n";
// return the vCard content as a downloadable response
return response($vCard)
->header('Content-Type', 'text/vcard')
->header('Content-Disposition', 'attachment; filename=vcard.vcf');
}
//Show link, click number, up link in links page
public function showLinks()
{

View File

@ -6,18 +6,19 @@
"license": "GPL-3.0-or-later",
"require": {
"php": "^7.3|^8.0",
"codedge/laravel-selfupdater": "^3.6",
"awssat/laravel-visits": "^4.0",
"codedge/laravel-selfupdater": "^3.6",
"cohensive/oembed": "^0.16",
"doctrine/dbal": "^3.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^3.0",
"geo-sot/laravel-env-editor": "^2.0",
"guzzlehttp/guzzle": "^7.4",
"jeroendesloovere/vcard": "^1.7",
"laravel/framework": "^9.52.4",
"laravel/socialite": "^5.5",
"laravel/tinker": "^2.5",
"spatie/laravel-backup": "^8.17",
"cohensive/oembed": "^0.16"
"spatie/laravel-backup": "^8.17"
},
"require-dev": {
"spatie/laravel-ignition": "^1.0",

2734
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -196,6 +196,13 @@ class LinkType extends Migration
'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.'
]);
DB::table($this->TableName)->updateOrInsert([
'typename' => 'vcard',
'title' => 'Vcard',
'icon' => 'bi bi-person-square',
'description' => 'Create or upload an electronic business card.'
]);
}
}

View File

@ -398,6 +398,10 @@ class ButtonSeeder extends Seeder
'name' => 'bookwyrm'
],
[
'name' => 'vcard'
],
];
Button::insert($buttons);

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><svg fill="#fff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M20 4H4c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zM8.715 8c1.151 0 2 .849 2 2s-.849 2-2 2-2-.849-2-2 .848-2 2-2zm3.715 8H5v-.465c0-1.373 1.676-2.785 3.715-2.785s3.715 1.412 3.715 2.785V16zM19 15h-4v-2h4v2zm0-4h-5V9h5v2z"/></svg>

After

Width:  |  Height:  |  Size: 396 B

View File

@ -143,6 +143,13 @@ use Illuminate\Support\Facades\File;
'icon' => 'bi bi-telephone-fill',
'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.'
]);
DB::table('link_types')->updateOrInsert([
'typename' => 'vcard',
'title' => 'Vcard',
'icon' => 'bi bi-person-square',
'description' => 'Create or upload an electronic business card.'
]);
} catch (exception $e) {}
// Changes saved profile images from littlelink_name to IDs.

View File

@ -0,0 +1,6 @@
<a class="button button-{{ $params->button }} button button-hover icon-hover" rel="noopener noreferrer nofollow" href="{{ route('clickNumber') . '/' . $link->id . '/' . $link->link}}" @if(theme('open_links_in_same_tab') !="true" )target="_blank" @endif>
<img alt="button-icon" class="icon hvr-icon" src="@if(theme('use_custom_icons') == " true"){{ url('themes/' . $GLOBALS['themeName'] . '/extra/custom-icons')}}/{{$params->button}}{{theme('custom_icon_extension')}} @else{{ asset('\/littlelink/icons\/') . $params->button }}.svg @endif">
{{ ucfirst($link->title) }}
</a>

View File

@ -0,0 +1,108 @@
<?php use App\Models\Button; $button = Button::find($button_id); if(isset($button->name)){$buttonName = $button->name;}else{$buttonName = 0;} ?>
<select style="display:none" name="button" class="form-control"><option class="button button-default email" value="vcard">Vcard</option></select>
<label for='title' class='form-label'>Custom Title</label>
<input type='text' name='link_title' value='' class='form-control' />
<span class='small text-muted'>Leave blank for default title</span><br>
<br><h5>Upload existing file</h5>
<div class="form-group col-lg-8">
<label>Vcard</label>
<input type="file" accept="text/vcard" class="form-control-file" name="vcard">
</div>
<br><h4>Name</h4>
<label for='prefix' class='form-label'>Prefix</label>
<input type='text' name='prefix' value='' class='form-control'/>
<br>
<label for='first_name' class='form-label'>First Name</label>
<input type='text' name='first_name' value='' class='form-control'/>
<br>
<label for='middle_name' class='form-label'>Middle Name</label>
<input type='text' name='middle_name' value='' class='form-control'/>
<br>
<label for='last_name' class='form-label'>Last Name</label>
<input type='text' name='last_name' value='' class='form-control'/>
<br>
<label for='suffix' class='form-label'>Suffix</label>
<input type='text' name='suffix' value='' class='form-control'/>
<br>
{{-- <label for='nickname' class='form-label'>Nickname</label>
<input type='text' name='nickname' value='' class='form-control'/>
<br> --}}
<br><h4>Work</h4>
<label for='organization' class='form-label'>Organization</label>
<input type='text' name='organization' value='' class='form-control'/>
<br>
<label for='title' class='form-label'>Title</label>
<input type='text' name='title' value='' class='form-control'/>
<br>
<label for='role' class='form-label'>Role</label>
<input type='text' name='role' value='' class='form-control'/>
<br>
<label for='work_url' class='form-label'>Work URL</label>
<input type='url' name='work_url' value='' class='form-control'/>
<br>
<br><h4>Emails</h4>
<label for='email' class='form-label'>Email</label>
<input type='email' name='email' value='' class='form-control'/>
<span class='small text-muted'>Enter your personal email</span>
<br>
<label for='work_email' class='form-label'>Work Email</label>
<input type='email' name='work_email' value='' class='form-control'/>
<span class='small text-muted'>Enter your work email</span>
<br>
<br><h4>Phones</h4>
<label for='home_phone' class='form-label'>Home Phone</label>
<input type='tel' name='home_phone' value='' class='form-control'/>
<br>
<label for='work_phone' class='form-label'>Work Phone</label>
<input type='tel' name='work_phone' value='' class='form-control'/>
<br>
<label for='cell_phone' class='form-label'>Cell Phone</label>
<input type='tel' name='cell_phone' value='' class='form-control'/>
<br>
<br><h4>Home Address</h4>
<label for='home_address_label' class='form-label'>Label</label>
<input type='text' name='home_address_label' value='' class='form-control'/>
<br>
<label for='home_address_street' class='form-label'>Street</label>
<input type='text' name='home_address_street' value='' class='form-control'/>
<br>
<label for='home_address_city' class='form-label'>City</label>
<input type='text' name='home_address_city' value='' class='form-control'/>
<br>
<label for='home_address_state' class='form-label'>State/Province</label>
<input type='text' name='home_address_state' value='' class='form-control'/>
<br>
<label for='home_address_zip' class='form-label'>Zip/Postal Code</label>
<input type='text' name='home_address_zip' value='' class='form-control'/>
<br>
<label for='home_address_country' class='form-label'>Country</label>
<input type='text' name='home_address_country' value='' class='form-control'/>
<br>
<br><h4>Work Address</h4>
<label for='work_address_label' class='form-label'>Label</label>
<input type='text' name='work_address_label' value='' class='form-control'/>
<br>
<label for='work_address_street' class='form-label'>Street</label>
<input type='text' name='work_address_street' value='' class='form-control'/>
<br>
<label for='work_address_city' class='form-label'>City</label>
<input type='text' name='work_address_city' value='' class='form-control'/>
<br>
<label for='work_address_state' class='form-label'>State/Province</label>
<input type='text' name='work_address_state' value='' class='form-control'/>
<br>
<label for='work_address_zip' class='form-label'>Zip/Postal Code</label>
<input type='text' name='work_address_zip' value='' class='form-control'/>
<br>
<label for='work_address_country' class='form-label'>Country</label>
<input type='text' name='work_address_country' value='' class='form-control'/>
<br>

View File

@ -336,6 +336,9 @@ function get_operating_system() {
@case('text')
<div class="fadein"><span style="">@if(env('ALLOW_USER_HTML') === true){!! $link->title !!}@else{{ $link->title }}@endif</span></div>
@break
@case('vcard')
<div style="--delay: {{ $initial++ }}s" class="button-entrance"><a class="button button-default button button-hover icon-hover" rel="noopener noreferrer nofollow" href="{{ route('vcard') . '/' . $link->id }}"><img alt="button-icon" class="icon hvr-icon" src="@if(theme('use_custom_icons') == "true"){{ url('themes/' . $GLOBALS['themeName'] . '/extra/custom-icons')}}/vcard{{theme('custom_icon_extension')}} @else{{ asset('\/littlelink/icons\/')}}vcard.svg @endif"></i>{{ $link->title }}</a></div>
@break
@case('custom')
@if($link->custom_css === "" or $link->custom_css === "NULL" or (theme('allow_custom_buttons') == "false"))
<div style="--delay: {{ $initial++ }}s" class="button-entrance"><a class="button button-{{ $link->name }} button button-hover icon-hover" rel="noopener noreferrer nofollow" href="{{ route('clickNumber') . '/' . $link->id . "?" . $link->link }}" @if(theme('open_links_in_same_tab') != "true")target="_blank"@endif ><i style="color: {{$link->custom_icon}}" class="icon hvr-icon fa {{$link->custom_icon}}"></i>{{ $link->title }}</a></div>

View File

@ -73,7 +73,7 @@ The 'Heading' button will be replaced with a sub-heading, where the title define
<div class="d-flex flex-row flex-wrap p-3">
@php
$custom_order = [1, 2, 6, 7, 3, 4, 5,];
$custom_order = [1, 2, 8, 6, 7, 3, 4, 5,];
$sorted = $LinkTypes->sortBy(function ($item) use ($custom_order) {
return array_search($item['id'], $custom_order);
});

View File

@ -92,6 +92,7 @@ Route::get('/pages/'.strtolower(env('TITLE_FOOTER_TERMS')), [AdminController::cl
Route::get('/pages/'.strtolower(env('TITLE_FOOTER_PRIVACY')), [AdminController::class, 'pagesPrivacy'])->name('pagesPrivacy');
Route::get('/pages/'.strtolower(env('TITLE_FOOTER_CONTACT')), [AdminController::class, 'pagesContact'])->name('pagesContact');
Route::get('/theme/@{littlelink}', [UserController::class, 'theme'])->name('theme');
Route::get('/vcard/{id?}', [UserController::class, 'vcard'])->name('vcard');
//User route
Route::group([