pdo = $pdo; } public function table($table) { $this->table = $table; return $this; } // Notice the new $boolean parameter (defaults to 'AND') public function where($column, $operator, $value = null, $boolean = 'AND') { if ($value === null) { $value = $operator; $operator = '='; } $paramName = 'where_' . str_replace('.', '_', $column) . '_' . count($this->params); // If this is the first where clause, we don't need 'AND' or 'OR' $prefix = empty($this->where) ? '' : strtoupper($boolean) . ' '; $this->where[] = "{$prefix}{$column} {$operator} :{$paramName}"; $this->params[$paramName] = $value; return $this; } // orWhere simply calls where() but passes 'OR' public function orWhere($column, $operator, $value = null) { return $this->where($column, $operator, $value, 'OR'); } // Sort the results public function orderBy($column, $direction = 'ASC') { $direction = strtoupper($direction) === 'DESC' ? 'DESC' : 'ASC'; $this->orderBy[] = "{$column} {$direction}"; return $this; } // Limit the number of results public function limit(int $limit) { $this->limit = $limit; return $this; } // Fetch a single record instead of an array of arrays public function first() { $this->limit(1); $result = $this->get(); return $result ? $result[0] : null; } public function getOld() { $sql = "SELECT * FROM {$this->table}"; // Changed implode from ' AND ' to ' ' because the prefix handles it now if (!empty($this->where)) { $sql .= " WHERE " . implode(' ', $this->where); } if (!empty($this->orderBy)) { $sql .= " ORDER BY " . implode(', ', $this->orderBy); } if ($this->limit !== null) { $sql .= " LIMIT {$this->limit}"; } $stmt = $this->pdo->prepare($sql); $stmt->execute($this->params); return $stmt->fetchAll(); } public function get() { // Use the new selects property instead of hardcoded '*' $sql = "SELECT {$this->selects} FROM {$this->table}"; // Add joins immediately after the FROM clause if (!empty($this->joins)) { $sql .= " " . implode(' ', $this->joins); } if (!empty($this->where)) { $sql .= " WHERE " . implode(' ', $this->where); } if (!empty($this->orderBy)) { $sql .= " ORDER BY " . implode(', ', $this->orderBy); } if ($this->limit !== null) { $sql .= " LIMIT {$this->limit}"; } $stmt = $this->pdo->prepare($sql); $stmt->execute($this->params); return $stmt->fetchAll(); } public function insert(array $data) { $columns = implode(', ', array_keys($data)); $placeholders = ':' . implode(', :', array_keys($data)); $sql = "INSERT INTO {$this->table} ({$columns}) VALUES ({$placeholders})"; return $this->pdo->prepare($sql)->execute($data); } public function update(array $data) { $fields = ""; foreach ($data as $key => $value) { $fields .= "{$key} = :{$key}, "; } $fields = rtrim($fields, ', '); $sql = "UPDATE {$this->table} SET {$fields}"; if (!empty($this->where)) { $sql .= " WHERE " . implode(' ', $this->where); } return $this->pdo->prepare($sql)->execute(array_merge($data, $this->params)); } public function delete() { $sql = "DELETE FROM {$this->table}"; if (!empty($this->where)) { $sql .= " WHERE " . implode(' ', $this->where); } return $this->pdo->prepare($sql)->execute($this->params); } // Specify exactly which columns to return public function select($columns) { // Allow passing an array ['id', 'name'] or a raw string 'id, name' $this->selects = is_array($columns) ? implode(', ', $columns) : $columns; return $this; } // The main join method public function join($table, $firstColumn, $operator, $secondColumn, $type = 'INNER') { $this->joins[] = "{$type} JOIN {$table} ON {$firstColumn} {$operator} {$secondColumn}"; return $this; } // A helpful shortcut for LEFT JOINS public function leftJoin($table, $firstColumn, $operator, $secondColumn) { return $this->join($table, $firstColumn, $operator, $secondColumn, 'LEFT'); } } ?>