How to create Vcard in Codeigniter ?

             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. This guide demonstrates how to create vCard files in CodeIgniter and dynamically generate and download them.

CodeIgniter 4 vCard: Dynamically Create a vCard File Using CodeIgniter 4

Table Of Content

1 Prerequisites

1.) PHP version of >= 8.2
2.) Composer
3.) Mysql

2 Introduction

This article explores how to create vCard files in CodeIgniter. You’ll learn how to dynamically generate vCard files using the CodeIgniter vCard library, enabling features such as exporting and downloading vCards.

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

3.2 Configure Environment and MySql Database

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 new controller named ContactController for handling the process of generating vCards:

php spark make:controller ContactController

Controller Function to Export and Download vCard in CodeIgniter:

<?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;
    }

}
?>

This demonstrates how to generate vCard files in CodeIgniter and facilitates downloading them.

6 Create a View

Create index.php in app/Views for listing contacts and enabling vCard generation.

  <!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 illustrated how to create, generate, and download vCard files in CodeIgniter using the CodeIgniter vCard library. The process enables seamless vCard creation and export functionality in your projects.

Tags