Tutorial Upload dan Tampil File PDF Portfolio dengan CodeIgniter 4

 


Daftar Isi

  1. Pendahuluan

  2. Persiapan Lingkungan

  3. Membuat Database dengan PhpMyAdmin

  4. Konfigurasi CodeIgniter 4

  5. Membuat Model

  6. Membuat Controller

  7. Membuat View

  8. Menjalankan Aplikasi

  9. Kesimpulan

1. Pendahuluan

Tutorial ini akan menjelaskan cara membuat sistem upload file PDF portfolio menggunakan framework CodeIgniter 4 dengan database MySQL yang dikelola melalui PhpMyAdmin. Sistem ini akan memungkinkan pengguna untuk mengunggah file PDF portfolio, menyimpan informasi file di database, dan menampilkan link untuk membuka file PDF di tab baru.

2. Persiapan Lingkungan

Sebelum memulai, pastikan Anda sudah menginstal:

  • PHP versi 7.4 atau lebih tinggi

  • MySQL/MariaDB

  • Web server (Apache/Nginx)

  • Composer

  • CodeIgniter 4

Jika belum memiliki project CodeIgniter 4, buat dengan perintah:

bash

composer create-project codeigniter4/appstarter ci4-portfolio-upload

cd ci4-portfolio-upload

3. Membuat Database dengan PhpMyAdmin

Langkah 1: Buka PhpMyAdmin

Akses PhpMyAdmin melalui browser (biasanya di http://localhost/phpmyadmin).

Langkah 2: Buat Database Baru

  1. Klik "New" di panel kiri

  2. Masukkan nama database (misalnya ci4_portfolio_library)

  3. Pilih collation utf8mb4_general_ci

  4. Klik "Create"

Langkah 3: Buat Tabel untuk File PDF

  1. Pilih database ci4_portfolio_library

  2. Klik tab "SQL" dan masukkan query berikut:

sql

CREATE TABLE portfolios (

    id INT AUTO_INCREMENT PRIMARY KEY,

    title VARCHAR(255) NOT NULL,

    file_name VARCHAR(255) NOT NULL,

    file_path VARCHAR(255) NOT NULL,

    file_type VARCHAR(100) NOT NULL,

    file_size INT NOT NULL,

    description TEXT,

    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

  1. Klik "Go" untuk mengeksekusi query

4. Konfigurasi CodeIgniter 4

Langkah 1: Konfigurasi Database

Edit file .env di root project CodeIgniter 4:

Copy

CI_ENVIRONMENT = development


database.default.hostname = localhost

database.default.database = ci4_portfolio_library

database.default.username = root

database.default.password = 

database.default.DBDriver = MySQLi

Langkah 2: Konfigurasi Upload Path

Buat folder untuk menyimpan file PDF:

bash

Copy

mkdir -p public/uploads/portfolios

5. Membuat Model

Buat file app/Models/PortfolioModel.php:

php

Copy

<?php


namespace App\Models;


use CodeIgniter\Model;


class PortfolioModel extends Model

{

    protected $table = 'portfolios';

    protected $primaryKey = 'id';

    protected $allowedFields = [

        'title', 'file_name', 'file_path', 'file_type', 

        'file_size', 'description'

    ];

    protected $useTimestamps = true;

    protected $createdField = 'uploaded_at';

    protected $updatedField = '';

    protected $deletedField = '';


    // Fungsi untuk mendapatkan semua portfolio

    public function getAllPortfolios()

    {

        return $this->orderBy('uploaded_at', 'DESC')->findAll();

    }


    // Fungsi untuk mendapatkan satu portfolio berdasarkan ID

    public function getPortfolio($id)

    {

        return $this->find($id);

    }

}

6. Membuat Controller

Buat file app/Controllers/Portfolio.php:

php

Copy

<?php


namespace App\Controllers;


use App\Models\PortfolioModel;

use CodeIgniter\Files\File;


class Portfolio extends BaseController

{

    protected $portfolioModel;

    

    public function __construct()

    {

        $this->portfolioModel = new PortfolioModel();

    }


    // Halaman beranda - menampilkan semua portfolio

    public function index()

    {

        $data = [

            'title' => 'Koleksi Portfolio',

            'portfolios' => $this->portfolioModel->getAllPortfolios()

        ];

        

        return view('portfolio/index', $data);

    }


    // Halaman form upload

    public function upload()

    {

        $data = [

            'title' => 'Upload Portfolio PDF Baru'

        ];

        

        return view('portfolio/upload', $data);

    }


    // Proses upload portfolio

    public function save()

    {

        // Validasi input

        $rules = [

            'title' => 'required|min_length[3]|max_length[255]',

            'userfile' => [

                'uploaded[userfile]',

                'mime_in[userfile,application/pdf]',

                'max_size[userfile,5120]', // 5MB max

            ],

            'description' => 'permit_empty|min_length[3]'

        ];


        if (!$this->validate($rules)) {

            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());

        }


        // Ambil file yang diupload

        $file = $this->request->getFile('userfile');


        // Cek apakah file valid

        if (!$file->isValid()) {

            return redirect()->back()->with('error', 'File tidak valid');

        }


        // Pindahkan file ke direktori uploads

        $newName = $file->getRandomName();

        $file->move('uploads/portfolios', $newName);


        // Simpan info file ke database

        $filepath = 'uploads/portfolios/' . $newName;

        

        $this->portfolioModel->save([

            'title' => $this->request->getPost('title'),

            'description' => $this->request->getPost('description'),

            'file_name' => $newName,

            'file_path' => $filepath,

            'file_type' => $file->getClientMimeType(),

            'file_size' => $file->getSize()

        ]);


        return redirect()->to('/portfolio')->with('message', 'Portfolio berhasil diupload');

    }


    // Halaman detail portfolio

    public function detail($id)

    {

        $data = [

            'title' => 'Detail Portfolio',

            'portfolio' => $this->portfolioModel->getPortfolio($id)

        ];

        

        if (empty($data['portfolio'])) {

            return redirect()->to('/portfolio');

        }

        

        return view('portfolio/detail', $data);

    }

}

7. Membuat View

Langkah 1: Buat Template Layout

Buat file app/Views/layout/template.php:

php

Copy

<!DOCTYPE html>

<html lang="id">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title><?= $title ?? 'Koleksi Portfolio CI4'; ?></title>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">

</head>

<body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">

        <div class="container">

            <a class="navbar-brand" href="<?= base_url('portfolio') ?>">Koleksi Portfolio CI4</a>

            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">

                <span class="navbar-toggler-icon"></span>

            </button>

            <div class="collapse navbar-collapse" id="navbarNav">

                <ul class="navbar-nav">

                    <li class="nav-item">

                        <a class="nav-link" href="<?= base_url('portfolio') ?>">Beranda</a>

                    </li>

                    <li class="nav-item">

                        <a class="nav-link" href="<?= base_url('portfolio/upload') ?>">Upload Portfolio</a>

                    </li>

                </ul>

            </div>

        </div>

    </nav>


    <div class="container mt-4">

        <?php if(session()->getFlashdata('message')): ?>

            <div class="alert alert-success">

                <?= session()->getFlashdata('message') ?>

            </div>

        <?php endif; ?>

        

        <?php if(session()->getFlashdata('errors')): ?>

            <div class="alert alert-danger">

                <ul class="mb-0">

                <?php foreach(session()->getFlashdata('errors') as $error): ?>

                    <li><?= $error ?></li>

                <?php endforeach; ?>

                </ul>

            </div>

        <?php endif; ?>

        

        <?= $this->renderSection('content') ?>

    </div>


    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

</body>

</html>

Langkah 2: Buat Halaman Beranda

Buat folder app/Views/portfolio dan file app/Views/portfolio/index.php:

php

Copy

<?= $this->extend('layout/template') ?>


<?= $this->section('content') ?>

<h1><?= $title ?></h1>

<p>Berikut adalah koleksi portfolio PDF yang telah diupload.</p>


<div class="row mb-4">

    <div class="col">

        <a href="<?= base_url('portfolio/upload') ?>" class="btn btn-primary">Upload Portfolio Baru</a>

    </div>

</div>


<div class="row">

    <?php if(empty($portfolios)): ?>

        <div class="col-12">

            <div class="alert alert-info">

                Belum ada portfolio yang diupload. Silakan upload portfolio terlebih dahulu.

            </div>

        </div>

    <?php else: ?>

        <div class="col-12">

            <div class="table-responsive">

                <table class="table table-striped table-hover">

                    <thead>

                        <tr>

                            <th>No</th>

                            <th>Judul</th>

                            <th>Deskripsi</th>

                            <th>Ukuran</th>

                            <th>Diupload</th>

                            <th>Aksi</th>

                        </tr>

                    </thead>

                    <tbody>

                        <?php $i = 1; foreach($portfolios as $portfolio): ?>

                            <tr>

                                <td><?= $i++ ?></td>

                                <td><?= $portfolio['title'] ?></td>

                                <td><?= substr($portfolio['description'] ?? '-', 0, 50) . (strlen($portfolio['description'] ?? '') > 50 ? '...' : '') ?></td>

                                <td><?= round($portfolio['file_size'] / 1024, 2) ?> KB</td>

                                <td><?= date('d-m-Y H:i', strtotime($portfolio['uploaded_at'])) ?></td>

                                <td>

                                    <a href="<?= base_url($portfolio['file_path']) ?>" class="btn btn-primary btn-sm" target="_blank">

                                        <i class="bi bi-file-earmark-pdf"></i> Lihat PDF

                                    </a>

                                    <a href="<?= base_url('portfolio/detail/'.$portfolio['id']) ?>" class="btn btn-info btn-sm">Detail</a>

                                </td>

                            </tr>

                        <?php endforeach; ?>

                    </tbody>

                </table>

            </div>

        </div>

    <?php endif; ?>

</div>

<?= $this->endSection() ?>

Langkah 3: Buat Halaman Upload

Buat file app/Views/portfolio/upload.php:

php

Copy

<?= $this->extend('layout/template') ?>


<?= $this->section('content') ?>

<h1><?= $title ?></h1>


<div class="row">

    <div class="col-md-8">

        <div class="card">

            <div class="card-body">

                <form action="<?= base_url('portfolio/save') ?>" method="post" enctype="multipart/form-data">

                    <div class="mb-3">

                        <label for="title" class="form-label">Judul Portfolio</label>

                        <input type="text" class="form-control" id="title" name="title" required value="<?= old('title') ?>">

                    </div>

                    

                    <div class="mb-3">

                        <label for="userfile" class="form-label">Pilih File PDF</label>

                        <input type="file" class="form-control" id="userfile" name="userfile" required accept="application/pdf">

                        <div class="form-text text-muted">Format yang diizinkan: PDF. Maksimal 5MB.</div>

                    </div>

                    

                    <div class="mb-3">

                        <label for="description" class="form-label">Deskripsi (Opsional)</label>

                        <textarea class="form-control" id="description" name="description" rows="3"><?= old('description') ?></textarea>

                    </div>

                    

                    <div class="d-flex">

                        <button type="submit" class="btn btn-primary">Upload</button>

                        <a href="<?= base_url('portfolio') ?>" class="btn btn-secondary ms-2">Kembali</a>

                    </div>

                </form>

            </div>

        </div>

    </div>

    

    <div class="col-md-4">

        <div class="card">

            <div class="card-header">Petunjuk</div>

            <div class="card-body">

                <p>Untuk mengupload portfolio PDF:</p>

                <ol>

                    <li>Masukkan judul portfolio</li>

                    <li>Pilih file PDF dari komputer Anda</li>

                    <li>Tambahkan deskripsi jika diperlukan</li>

                    <li>Klik tombol "Upload"</li>

                </ol>

            </div>

        </div>

    </div>

</div>

<?= $this->endSection() ?>

Langkah 4: Buat Halaman Detail

Buat file app/Views/portfolio/detail.php:

php

Copy

<?= $this->extend('layout/template') ?>


<?= $this->section('content') ?>

<div class="row mb-4">

    <div class="col">

        <a href="<?= base_url('portfolio') ?>" class="btn btn-secondary">Kembali ke Daftar</a>

    </div>

</div>


<div class="card">

    <div class="card-body">

        <div class="row">

            <div class="col-md-8">

                <h1><?= $portfolio['title'] ?></h1>

                

                <?php if(!empty($portfolio['description'])): ?>

                    <div class="mb-4">

                        <h5>Deskripsi:</h5>

                        <p><?= $portfolio['description'] ?></p>

                    </div>

                <?php endif; ?>

                

                <table class="table">

                    <tr>

                        <th>Nama File</th>

                        <td><?= $portfolio['file_name'] ?></td>

                    </tr>

                    <tr>

                        <th>Tipe File</th>

                        <td><?= $portfolio['file_type'] ?></td>

                    </tr>

                    <tr>

                        <th>Ukuran File</th>

                        <td><?= round($portfolio['file_size'] / 1024, 2) ?> KB</td>

                    </tr>

                    <tr>

                        <th>Diupload Pada</th>

                        <td><?= date('d-m-Y H:i', strtotime($portfolio['uploaded_at'])) ?></td>

                    </tr>

                </table>

            </div>

            <div class="col-md-4">

                <div class="card text-center">

                    <div class="card-body">

                        <i class="bi bi-file-earmark-pdf display-1 text-danger"></i>

                        <h5 class="card-title mt-3">Lihat PDF</h5>

                        <p class="card-text">Klik tombol di bawah untuk membuka file PDF</p>

                        <a href="<?= base_url($portfolio['file_path']) ?>" class="btn btn-primary btn-lg" target="_blank">

                            <i class="bi bi-file-earmark-pdf"></i> Buka PDF

                        </a>

                    </div>

                </div>

            </div>

        </div>

    </div>

</div>

<?= $this->endSection() ?>

8. Konfigurasi Routes

Edit file app/Config/Routes.php untuk menambahkan routes:

php

Copy

$routes->get('/portfolio', 'Portfolio::index');

$routes->get('/portfolio/upload', 'Portfolio::upload');

$routes->post('/portfolio/save', 'Portfolio::save');

$routes->get('/portfolio/detail/(:num)', 'Portfolio::detail/$1');

9. Menjalankan Aplikasi

Langkah 1: Mulai Server Development

bash

Copy

php spark serve

Langkah 2: Akses Aplikasi

Buka browser dan kunjungi http://localhost:8080/portfolio

Kesimpulan

Sekarang Anda telah berhasil membuat sistem upload dan tampil file PDF portfolio menggunakan CodeIgniter 4 dan MySQL/MySQLi. Sistem ini mencakup:

  1. Database untuk menyimpan informasi file PDF portfolio

  2. Fungsi upload file PDF dengan validasi

  3. Halaman daftar yang menampilkan semua portfolio dengan link untuk membuka file PDF di tab baru

  4. Halaman detail untuk melihat informasi lengkap portfolio


Komentar

Postingan populer dari blog ini

Takir Plontang