Laravel 11 Apexcharts Example Tutorial A vCard file, also known as a VCF (Virtual Contact File), is a standard format for sharing contact information. vCards can include: personal information, phone numbers, email addresses, and employment information
Table Of Content
1 Prerequisites
1.) PHP version of >= 8.2
2.) Composer
3.) Mysql
2 Introduction
Inside this article, we will see how to Create a vCard File Using Codeigniter 4
3 Create / Install a Codeigniter 4 Project
3.1 Install Codeigniter 4 Project
First, make sure your computer has a composer.
Use the following command to install new Codeigniter Project.
composer create-project codeigniter4/appstarter ci-4-vcard-app
Then, navigate to your project directory:
cd ci-4-vcard-app
Rename the env file to .env and set the development mode in the .env file also configure mysql:
# CI_ENVIRONMENT = production
CI_ENVIRONMENT = development
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ci4_vcard
DB_USERNAME=root
DB_PASSWORD=
4 Create Migration and Model
Create a migration for the
events table and a model to manage data:
php spark make:model Contact
Edit
app/Models/Contact.php to configure the model:
<?php
namespace App\Models;
use CodeIgniter\Model;
class Contact extends Model
{
protected $table = 'users';
protected $primaryKey = 'id';
protected $allowedFields = ['name','email','phone','created_at','updated_at'];
}
Create a migration file for the
users table:
php spark make:migration AddContact
Edit the migration file to define the table structure:
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddContact extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'BIGINT',
'constraint' => 255,
'unsigned' => true,
'auto_increment' => true
],
'name' => [
'type' => 'VARCHAR',
'constraint' => '255',
],
'email' => [
'type' => 'longtext'
],
'phone' => [
'type' => 'longtext'
],
'created_at' => [
'type' => 'TIMESTAMP',
'null' => true
],
'updated_at' => [
'type' => 'TIMESTAMP',
'null' => true
],
]);
$this->forge->addPrimaryKey('id');
$this->forge->createTable('contacts');
}
public function down()
{
$this->forge->dropTable('contacts');
}
}
Run the migration:
php spark migrate
5 Create New Controller - ContactController
Create a controller to handle Chart process:
php spark make:controller ContactController
In
app/Controllers/ContactController.php , define the index and filterData function:
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\Contact;
class ContactController extends BaseController
{
public function index()
{
return view('users');
}
public function store()
{
$jsonStr = file_get_contents('php://input');
$jsonObj = json_decode($jsonStr);
$contact_data = $jsonObj->contact_data;
$model = new Contact();
$data = [
"name" => $contact_data[0],
"email" => $contact_data[1],
"phone" => $contact_data[2],
"created_at"=>date('Y-m-d H:i:s')
];
$model->insert($data);
$json_data['status']=1;
return $this->response->setJSON($json_data);
}
public function getUsers()
{
$model = new Contact();
$request = \Config\Services::request();
$limit = $request->getPost('length');
$start = $request->getPost('start');
$order_column_value = $request->getPost('order')[0]['column'];
$order=$request->getPost('columns')[$order_column_value]['data'];
$dir = $request->getPost('order')[0]['dir'];
$totalData = $model->countAll();
$totalFiltered = $totalData;
if(empty($request->getPost('search')['value']))
{
$users = $model->orderBy($order, $dir)->findAll($limit, $start);
}
else {
$search = $request->getPost('search')['value'];
$users = $model->like('name', $search)->orLike('email', $search)->orderBy($order, $dir)->findAll($limit, $start);
$totalFiltered = $model->like('name', $search)->orLike('email', $search)->countAllResults();
}
$data = array();
if(!empty($users))
{
foreach ($users as $user)
{
$nestedData['id'] = $user['id'];
$nestedData['name'] = $user['name'];
$nestedData['email'] = $user['email'];
$nestedData['phone'] = $user['phone'];
$nestedData['created_at'] = $user['created_at'];
$nestedData['action'] = 'Download VCard ';
$data[] = $nestedData;
}
}
$json_data = array(
"draw" => intval($request->getPost('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data
);
return $this->response->setJSON($json_data);
}
public function exportvcard()
{
$model = new Contact();
$request = \Config\Services::request();
$id=$request->getUri()->getSegment(2);
$user=$model->find($id);
// Generate VCF content
$vcfContent = "BEGIN:VCARD\n";
$vcfContent .= "VERSION:3.0\n";
$vcfContent .= "FN:" . $user['name'] . "\n";
$vcfContent .= "TEL;TYPE=HOME,VOICE:" . $user['phone'] . "\n";
$vcfContent .= "EMAIL:" . $user['email'] . "\n";
$vcfContent .= "END:VCARD\n";
// Define the file name
$fileName = 'contact_' . $id . '.vcf';
// Set the headers to force download
header('Content-Type: text/vcard');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . strlen($vcfContent));
// Output the VCF content
echo $vcfContent;
// Stop further execution (optional, ensures the script doesn't continue)
exit;
}
}
?>
6 Create a View
Create the
index.php view file in
app/Views/ to List Contact and generate
dynamic vCard :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DataTables with CodeIgniter 4</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.11.4/css/dataTables.bootstrap5.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
* {
margin: 0;
padding: 0;
font-family: 'Poppins', sans-serif;
}
body {
background-color: #eee !important;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
.main {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 40px 30px 40px;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 15px;
box-shadow: rgba(0, 0, 0, 0.3) 0 5px 15px;
width: 60%;
height: 700px;
position: absolute;
}
.header-container {
display: flex;
justify-content: space-between;
width: 100%;
border-bottom: 1px solid;
margin-bottom: 20px;
padding-bottom: 10px;
}
.header-container > h3 {
font-weight: 500;
}
.tasks-container {
position: relative;
width: 100%;
}
.action-button {
display: flex;
justify-content: center;
}
.action-button > button {
width: 25px;
height: 25px;
font-size: 17px;
display: flex !important;
justify-content: center;
align-items: center;
margin: 0px 2px;
}
.dataTables_wrapper .dataTables_info {
position: absolute !important;
bottom: 20px !important;
}
</style>
</head>
<body>
<div class="main">
<div class="container">
<div class="header-container">
<h3>Contact Manager with Export to VCF</h3>
<button type="button" class="btn btn-dark btn-sm" onClick="addContact()">
Add Contact
</button>
</div>
<div class="tasks-container">
<table id="userTable" class="table table-bordered ">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Created At</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<!-- Data will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
<script>
$(document).ready(function() {
loadData();
});
function loadData()
{
$('#userTable').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "<?php echo base_url('usercontroller/getusers'); ?>",
"type": "POST"
},
"columns": [
{ data: 'id' },
{ data: 'name' },
{ data: 'email' },
{ data: 'phone' },
{ data: 'created_at' },
{ data: 'action' }
]
});
}
function addContact()
{
(async () => {
const { value: formValues } = await Swal.fire({
title: 'Add Contact',
confirmButtonText: 'Submit',
showCloseButton: true,
showCancelButton: true,
html:
'<input id="name" class="swal2-input" placeholder="Enter Name">' +
'<input id="email" class="swal2-input" placeholder="Enter Email Id">' +
'<input id="phone" class="swal2-input" placeholder="Enter Phone No">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('name').value,
document.getElementById('email').value,
document.getElementById('phone').value
]
}
});
if (formValues) {
// Add event
fetch("/store", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ contact_data: formValues}),
})
.then(response => response.json())
.then(data => {
if (data.status == 1) {
Swal.fire('Contact added successfully!', '', 'success');
loadData();
} else {
Swal.fire(data.error, '', 'error');
}
// Refetch events from all sources and rerender
calendar.refetchEvents();
})
.catch(console.error);
}
})()
}
</script>
</body>
</html>
7 Define a Route
In
app/Config/Routes.php , define routes for the FullCalenderController controller:
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->get('/', 'Home::index');
$routes->get('users', 'ContactController::index');
$routes->post('usercontroller/getusers', 'ContactController::getUsers');
$routes->get('exportvcard/(:num)', 'ContactController::exportvcard//$1');
$routes->post('store', 'ContactController::store');
8 Folder Structure
9 Run Web Server to Test the App
Use the following command to Test the App.
php spark serve
Visit the URL
http://localhost:8080/users
10 Conclusion
This guide walked you through How to Dynamically Create a vCard File Using Codeigniter 4
Tags