Untitled

 avatar
unknown
php
9 days ago
7.2 kB
6
Indexable
<?php
namespace App\Table;

use Exception;
use App\Model\Post;
use App\Model\Category;

/**
 * Classe Table
 * 
 * Classe de base pour toutes les tables dans la base de données.
 */
class Table
{
    /**
     * Connexion à la base de données.
     * 
     * @var \mysqli Connexion à la base de données MySQL.
     */
    protected $_connection;

    /**
     * Nom de la table.
     * 
     * @var string Nom de la table liée à cette instance de la classe.
     */
    protected $_table = null;

    /**
     * Constructeur pour initialiser la connexion à la base de données.
     * 
     * @param \mysqli $connection L'objet de connexion à la base de données.
     */
    public function __construct(\mysqli $connection)
    {
        $this->_connection = $connection;
    }

    /**
     * Récupère les données d'un post ou d'une catégorie par son ID.
     * 
     * @param int $id L'ID de l'élément à récupérer.
     * 
     * @return Category|Post L'objet correspondant au post ou à la catégorie.
     * 
     * @throws Exception Si l'élément n'est pas trouvé.
     */
    public function find(int $id): Category|Post
    {
        $stmt = $this->_connection->prepare(
            "SELECT * FROM ". $this->_table . " WHERE id = ?"
        );
        $stmt->bind_param("i", $id);
        $stmt->execute();
        $result = $stmt->get_result();
        $data = $result->fetch_assoc();

        if ($this->_table == "category") {
            // Créer et retourner un objet Category
            return new Category(
                $id,
                $data['name'],
                $data['slug']
            );
        } elseif ($this->_table == "post") {
            // Créer et retourner un objet Post
            return new Post(
                $data['id'],
                $data['name'],
                $data['slug'],
                $data['content'],
                $data['created_at']
            );
        }

        throw new Exception(
            "Élément introuvable dans la table {$this->_table}"
        );
    }

    /**
     * Vérifie si une valeur existe dans la table.
     * 
     * @param string $field Champ à rechercher dans la table.
     * @param mixed $value Valeur à rechercher pour ce champ.
     * @param int|null $except ID à exclure de la recherche 
     * (pour les mises à jour).
     * 
     * @return bool True si la valeur existe, false sinon.
     */
    public function exists(string $field, $value, ?int $except = null): bool
    {
        $query = "SELECT COUNT(id) 
                FROM " . $this->_table . " 
                WHERE " . $field . " = ?";
        
        if ($except !== null) {
            $query .= " AND id != ?";
        }

        $stmt = $this->_connection->prepare($query);

        $params = ($except !== null) ? ["si", $value, $except] : ["s", $value];
        $stmt->bind_param(...$params);  // L'opérateur splat est utilisé pour 
                                        // passer les paramètres

        $stmt->execute();
        $result = $stmt->get_result();
        $row = $result->fetch_row();

        return $row[0] > 0;
    }

    /**
     * Récupère tous les éléments de la table.
     * 
     * @return array L'ensemble des objets récupérés de la table 
     * (Post ou Category).
     */
    public function all(): array
    {
        $sql = "SELECT * FROM {$this->_table}";
        $result = $this->_connection->query($sql);

        if (!$result) {
            return [];
        }

        $objects = [];
        while ($data = $result->fetch_assoc()) {
            $object = new $this->_class(
                $data['id'], 
                $data['name'], 
                $data['slug']
            );
            $objects[] = $object;
        }

        return $objects;
    }

    /**
     * Supprime un enregistrement de la table.
     * 
     * @param int $id ID de l'élément à supprimer.
     * 
     * @throws Exception Si la suppression échoue.
     */
    public function delete(int $id)
    {
        $stmt = $this->_connection->prepare(
            "DELETE FROM {$this->_table} WHERE id = ?"
        );
        $stmt->bind_param("i", $id);
        $ok = $stmt->execute();
        if ($ok === false) {
            throw new Exception(
                "
            Imp. de sup. l'enr. avec l'ID {$id} dans la table {$this->_table}"
            );
        }
    }

    /**
     * Crée un nouvel enregistrement dans la table.
     * 
     * @param array<string, mixed> $data Données à insérer dans la table.
     * 
     * @return int L'ID de l'enregistrement nouvellement créé.
     * 
     * @throws Exception Si l'insertion échoue.
     */
    public function create(array $data): int
    {
        $sqlFields = array_keys($data);
        $placeholders = array_fill(0, count($data), '?');

        $params = "";
        $values = [];
        foreach ($data as $value) {
            if (is_int($value)) {
                $params .= "i";
            } elseif (is_float($value)) {
                $params .= "d";
            } else {
                $params .= "s";
            }
            $values[] = $value;
        }

        $stmt = $this->_connection->prepare(
            "INSERT INTO {$this->_table} (" . implode(', ', $sqlFields) . ") 
            VALUES (" . implode(', ', $placeholders) . ")"
        );

        $stmt->bind_param($params, ...$values);

        $ok = $stmt->execute();
        if ($ok === false) {
            throw new Exception(
                "
            Impossible de créer l'enregistrement dans la table {$this->_table}
            "
            );
        }

        return $this->_connection->insert_id;
    }

    /**
     * Met à jour un enregistrement dans la table.
     * 
     * @param array<string, mixed> $data Données à mettre à jour.
     * @param int $id ID de l'enregistrement à mettre à jour.
     * 
     * @throws Exception Si la mise à jour échoue.
     */
    public function update(array $data, int $id)
    {
        $sqlFields = array_keys($data);
        $setClause = implode(' = ?, ', $sqlFields) . ' = ?';

        $params = "";
        $values = [];
        foreach ($data as $value) {
            if (is_int($value)) {
                $params .= "i";
            } elseif (is_float($value)) {
                $params .= "d";
            } else {
                $params .= "s";
            }
            $values[] = $value;
        }

        $params .= "i";  // Ajouter l'ID au paramètre de requête
        $values[] = $id;

        $stmt = $this->_connection->prepare(
            "UPDATE {$this->_table} SET {$setClause} WHERE id = ?"
        );

        $stmt->bind_param($params, ...$values);

        $ok = $stmt->execute();
        if ($ok === false) {
            throw new Exception(
                "
            Imp. de maj l'enr. avec l'ID {$id} dans la table {$this->_table}
            "
            );
        }
    }
}
Leave a Comment