connexion = $connexion; $this->table = $table; $this->alias = $alias ?: $table; } /** * Désactive le filtrage multi-tenant (pour les tables système) */ public function withoutTenantFilter() { $this->useTenantFilter = false; return $this; } /** * Définit les colonnes à sélectionner */ public function select($columns) { $this->select = $columns; return $this; } /** * Ajoute une jointure */ public function join($table, $condition, $type = 'INNER') { $this->joins[] = "$type JOIN $table ON $condition"; return $this; } /** * Ajoute une condition WHERE */ public function where($condition, $params = []) { $this->where[] = $condition; if (is_array($params)) { $this->params = array_merge($this->params, $params); } return $this; } /** * Ajoute un ORDER BY */ public function orderBy($column, $direction = 'ASC') { $this->orderBy[] = "$column $direction"; return $this; } /** * Définit la limite */ public function limit($limit, $offset = null) { $this->limit = $limit; $this->offset = $offset; return $this; } /** * Construit et exécute la requête SELECT */ public function get() { $sql = $this->buildSelect(); $stmt = $this->connexion->prepare($sql); // Ajouter le filtrage multi-tenant si nécessaire if ($this->useTenantFilter && isset($_SESSION['niveau_acces']) && isset($_SESSION['eglise_id'])) { MultiTenant::bindTenantParams($stmt); } // Binder les autres paramètres foreach ($this->params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } /** * Construit et exécute la requête SELECT pour un seul résultat */ public function first() { $sql = $this->buildSelect(); $stmt = $this->connexion->prepare($sql); if ($this->useTenantFilter && isset($_SESSION['niveau_acces']) && isset($_SESSION['eglise_id'])) { MultiTenant::bindTenantParams($stmt); } foreach ($this->params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->execute(); return $stmt->fetch(PDO::FETCH_OBJ); } /** * Construit la requête SQL SELECT */ private function buildSelect() { $sql = "SELECT {$this->select} FROM {$this->table} {$this->alias}"; // Ajouter les jointures foreach ($this->joins as $join) { $sql .= " $join"; } // Construire les conditions WHERE $whereConditions = []; // Ajouter le filtre multi-tenant si nécessaire if ($this->useTenantFilter && isset($_SESSION['niveau_acces']) && isset($_SESSION['eglise_id'])) { $tenantFilter = MultiTenant::getWhereClause($this->alias); if ($tenantFilter !== '1=1' && $tenantFilter !== '1=0') { $whereConditions[] = $tenantFilter; } } // Ajouter les autres conditions $whereConditions = array_merge($whereConditions, $this->where); if (!empty($whereConditions)) { $sql .= " WHERE " . implode(' AND ', $whereConditions); } // Ajouter ORDER BY if (!empty($this->orderBy)) { $sql .= " ORDER BY " . implode(', ', $this->orderBy); } // Ajouter LIMIT if ($this->limit !== null) { $sql .= " LIMIT " . (int)$this->limit; if ($this->offset !== null) { $sql .= " OFFSET " . (int)$this->offset; } } return $sql; } /** * Méthode statique pour créer une nouvelle instance */ public static function table($connexion, $table, $alias = null) { return new self($connexion, $table, $alias); } } /** * Fonction helper pour obtenir une requête filtrée par eglise_id * Utilisation: $result = queryTenantFiltered($connexion, "SELECT * FROM table WHERE ...", $params); */ function queryTenantFiltered($connexion, $sql, $params = []) { // Si la requête contient déjà eglise_id ou concerne des tables système, retourner tel quel if (preg_match('/eglise_id|eglises|groupes|utilisateurs|permissions/i', $sql)) { $stmt = $connexion->prepare($sql); foreach ($params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } // Ajouter le filtre multi-tenant if (isset($_SESSION['niveau_acces']) && isset($_SESSION['eglise_id'])) { // Détecter le nom de la table principale if (preg_match('/FROM\s+([a-zA-Z_]+)\s*(?:AS\s+([a-zA-Z_]+))?/i', $sql, $matches)) { $table = $matches[1]; $alias = !empty($matches[2]) ? $matches[2] : $table; $tenantFilter = MultiTenant::getWhereClause($alias); if ($tenantFilter !== '1=1') { // Ajouter le filtre dans la clause WHERE if (preg_match('/WHERE\s+/i', $sql)) { $sql = preg_replace('/(WHERE\s+.*?)(\s*ORDER|\s*GROUP|\s*LIMIT|$)/is', '$1 AND ' . $tenantFilter . '$2', $sql); } else { // Ajouter la clause WHERE $sql = preg_replace('/(FROM\s+' . preg_quote($table, '/') . '\s*(?:AS\s+[a-zA-Z_]+)?)\s*(\s*ORDER|\s*GROUP|\s*LIMIT|$)/is', '$1 WHERE ' . $tenantFilter . '$2', $sql); } } } } $stmt = $connexion->prepare($sql); // Binder les paramètres du filtre multi-tenant if (isset($_SESSION['niveau_acces']) && isset($_SESSION['eglise_id'])) { MultiTenant::bindTenantParams($stmt); } // Binder les autres paramètres foreach ($params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_OBJ); } /** * Fonction helper pour exécuter une requête avec filtrage multi-tenant et retourner un seul résultat */ function queryTenantFilteredFirst($connexion, $sql, $params = []) { $results = queryTenantFiltered($connexion, $sql, $params); return !empty($results) ? $results[0] : null; }