Lewati ke konten
TubePress — gratis, self-hosted & aktif dikembangkan
Referensi pengembang

Model & basis data

Lapisan data TubePress: kelas model, helper Database PDO, prepared statement, skema basis data dan migrasi SQL berversi dijelaskan.

TubePress berkomunikasi dengan MySQL/MariaDB melalui dua lapisan tipis: model (satu kelas statis per entitas) dan helper Database (pembungkus kecil di atas PDO). Tidak ada ORM dan tidak ada query builder yang perlu dipelajari — hanya prepared statement dan nama metode yang mudah diprediksi.

Lapisan model

Setiap entitas inti memiliki model di src/Models/ yang mengekspos metode statis. Model yang tersedia adalah Video, Category, Tag, Performer, Channel, Comment, Page, User, Setting, Favorite, History, Report, ContactMessage, MenuConfig dan FooterConfig.

$video  = Video::find($id);            // one row (or null)
$latest = Video::all(['status' => 'published', 'limit' => 20]);
$id     = Video::create($data);        // returns new id
Video::update($id, ['title' => 'New title']);
Video::delete($id);

Model merangkum join dan filter yang spesifik untuk entitasnya — misalnya Video::find() mengembalikan video beserta kategori, tag, performer, dan channel yang terlampir, sehingga controller dan template tetap sederhana.

Helper Database

Untuk hal apa pun yang belum dicakup model, gunakan helper Database secara langsung. Setiap metode menggunakan prepared statement — jangan pernah menggabungkan input pengguna ke dalam SQL.

MetodeMengembalikanTujuan
Database::fetchOne($sql, $params)array\|nullBaris pertama yang cocok.
Database::fetchAll($sql, $params)arraySemua baris yang cocok.
Database::insert($table, $data)intSisipkan array asosiatif; mengembalikan id baru.
Database::update($table, $data, $where, $whereParams)intPerbarui; mengembalikan baris yang terpengaruh.
Database::delete($table, $where, $params)intHapus; mengembalikan baris yang terpengaruh.
Database::count($table, $where, $params)intJumlah baris.
Database::query($sql, $params)PDOStatementPernyataan apa pun, untuk kontrol penuh.
Database::transaction($callback)mixedJalankan closure dalam transaksi (commit/rollback otomatis).
$rows = Database::fetchAll(
    "SELECT * FROM videos WHERE status = ? ORDER BY id DESC LIMIT ?",
    ['published', 20]
);

$newId = Database::insert('categories', [
    'name' => 'Amateur',
    'slug' => 'amateur',
]);
Koneksi yang tangguh. Helper menggunakan utf8mb4, prepared statement nyata (tanpa emulasi) dan mode error exception, serta secara otomatis menghubungkan kembali sekali pada error "server has gone away" yang sesungguhnya — sehingga worker yang berjalan lama tetap bertahan saat MySQL timeout idle.

Transaksi

Bungkus penulisan multi-langkah agar semuanya berhasil atau semuanya di-rollback:

Database::transaction(function () use ($videoId, $catIds) {
    Database::delete('video_categories', 'video_id = ?', [$videoId]);
    foreach ($catIds as $cid) {
        Database::insert('video_categories', [
            'video_id' => $videoId, 'category_id' => $cid,
        ]);
    }
});

Skema

Database menggunakan skema MySQL yang bersih dan ternormalisasi. Tabel inti mencakup users, settings, categories, tags, performers, channels, videos dan tabel join video_categories, video_tags, video_performers — ditambah comments, user_favorites, user_history, video_likes, pages, plugins, themes dan migrations. Subsistem opsional menambahkan tabel mereka sendiri (pekerjaan impor, penyimpanan media, pekerjaan/server transcode, zona/spot iklan, laporan, sumber feed, tabel terjemahan dan lainnya) saat Anda mengaktifkannya.

Migrasi

Perubahan skema disimpan di sql/ sebagai file bernomor — 001_users.sql, 002_settings.sql, … — diterapkan secara berurutan oleh Migrator::run() selama instalasi dan setelah setiap pembaruan. Setiap migrasi bersifat aditif dan dicatat dalam tabel migrations sehingga tidak pernah berjalan dua kali.

  • Untuk memperluas skema dari plugin, sertakan pernyataan CREATE TABLE Anda dan jalankan dalam metode install() plugin (lihat Hooks & plugins).
  • Jangan pernah menomori ulang atau mengedit migrasi yang sudah diterapkan — tambahkan yang baru dengan nomor lebih tinggi.

Menulis model

Model hanyalah kelas statis yang membungkus helper Database untuk satu tabel:

class Promo
{
    public static function current(): ?array
    {
        return Database::fetchOne(
            "SELECT * FROM promos WHERE active = 1
             ORDER BY id DESC LIMIT 1"
        );
    }
}

Langkah selanjutnya

Masih kesulitan?

Buka tiket dari dasbor Anda dan tim kami akan membantu Anda.

Coba demo langsung → Unduh TubePress →