Aller au contenu
TubePress — gratuit, auto-hébergé & activement maintenu
Référence développeur

Modèles et base de données

La couche de données de TubePress : les classes de modèles, le helper Database PDO, les requêtes préparées, le schéma de base de données et les migrations SQL versionnées expliqués.

TubePress communique avec MySQL/MariaDB via deux couches légères : les modèles (une classe statique par entité) et le helper Database (un petit wrapper autour de PDO). Aucun ORM ni query builder à apprendre — seulement des requêtes préparées et des noms de méthodes prévisibles.

La couche modèle

Chaque entité principale possède un modèle dans src/Models/ exposant des méthodes statiques. Les modèles disponibles sont Video, Category, Tag, Performer, Channel, Comment, Page, User, Setting, Favorite, History, Report, ContactMessage, MenuConfig et 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);

Les modèles encapsulent les jointures et filtres propres à leur entité — par exemple Video::find() retourne la vidéo avec ses catégories, tags, interprètes et chaînes attachés, ce qui simplifie les contrôleurs et les templates.

Le helper Database

Pour tout ce qu'un modèle ne couvre pas déjà, utilisez le helper Database directement. Chaque méthode utilise des requêtes préparées — ne concaténez jamais une saisie utilisateur dans une requête SQL.

MéthodeRetourneUtilité
Database::fetchOne($sql, $params)array\|nullPremière ligne correspondante.
Database::fetchAll($sql, $params)arrayToutes les lignes correspondantes.
Database::insert($table, $data)intInsère un tableau associatif ; retourne le nouvel identifiant.
Database::update($table, $data, $where, $whereParams)intMise à jour ; retourne les lignes affectées.
Database::delete($table, $where, $params)intSuppression ; retourne les lignes affectées.
Database::count($table, $where, $params)intNombre de lignes.
Database::query($sql, $params)PDOStatementToute requête, pour un contrôle total.
Database::transaction($callback)mixedExécute une closure dans une transaction (commit/rollback automatique).
$rows = Database::fetchAll(
    "SELECT * FROM videos WHERE status = ? ORDER BY id DESC LIMIT ?",
    ['published', 20]
);

$newId = Database::insert('categories', [
    'name' => 'Amateur',
    'slug' => 'amateur',
]);
Connexions résilientes. Le helper utilise utf8mb4, de vraies requêtes préparées (sans émulation) et le mode erreur par exception, et il se reconnecte automatiquement une fois en cas de véritable erreur « server has gone away » — ainsi les workers de longue durée survivent à un timeout MySQL inactif.

Transactions

Enveloppez les écritures en plusieurs étapes pour qu'elles réussissent toutes ou soient toutes annulées :

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,
        ]);
    }
});

Le schéma

La base de données utilise un schéma MySQL propre et normalisé. Les tables principales comprennent users, settings, categories, tags, performers, channels, videos et les tables de jointure video_categories, video_tags, video_performers — ainsi que comments, user_favorites, user_history, video_likes, pages, plugins, themes et migrations. Les sous-systèmes optionnels ajoutent leurs propres tables (jobs d'import, stockages média, jobs/serveurs de transcodage, zones/spots publicitaires, signalements, sources de flux, tables de traduction, etc.) au fur et à mesure de leur activation.

Migrations

Les modifications du schéma se trouvent dans sql/ sous forme de fichiers numérotés — 001_users.sql, 002_settings.sql, … — appliqués dans l'ordre par Migrator::run() lors de l'installation et après chaque mise à jour. Chaque migration est additive et enregistrée dans la table migrations afin de n'être jamais exécutée deux fois.

  • Pour étendre le schéma depuis un plugin, fournissez vos instructions CREATE TABLE et exécutez-les dans la méthode install() du plugin (voir Hooks & plugins).
  • Ne renumérotez jamais une migration appliquée et ne la modifiez pas — ajoutez-en une nouvelle avec un numéro supérieur.

Écrire un modèle

Un modèle est simplement une classe statique qui encapsule le helper Database pour une table :

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

Étapes suivantes

Toujours bloqué ?

Ouvrez un ticket depuis votre tableau de bord et notre équipe vous assistera.

Essayer la démo en direct → Télécharger TubePress →